TTY/Serial driver fixes for 6.10-rc4

Here are some small tty and serial driver fixes that resolve som
 reported problems.  Included in here are:
   - n_tty lookahead buffer bugfix
   - WARN_ON() removal where it was not needed
   - 8250_dw driver bugfixes
   - 8250_pxa bugfix
   - sc16is7xx Kconfig fixes for reported build issues
 
 All of these have been in linux-next for over a week with no reported
 problems.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZm6+jQ8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+yl/xwCgjLYn51rN/qHGGCy7db5/+B+EeiEAoNXP9BGV
 6EmNQc5A9V2Ze+I6xSsE
 =aEiP
 -----END PGP SIGNATURE-----

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

Pull tty/serial driver fixes from Greg KH:
 "Here are some small tty and serial driver fixes that resolve som
  reported problems. Included in here are:

   - n_tty lookahead buffer bugfix

   - WARN_ON() removal where it was not needed

   - 8250_dw driver bugfixes

   - 8250_pxa bugfix

   - sc16is7xx Kconfig fixes for reported build issues

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

* tag 'tty-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: drop debugging WARN_ON_ONCE() from uart_write()
  serial: sc16is7xx: re-add Kconfig SPI or I2C dependency
  serial: sc16is7xx: rename Kconfig CONFIG_SERIAL_SC16IS7XX_CORE
  serial: port: Don't block system suspend even if bytes are left to xmit
  serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level
  serial: 8250_dw: Revert "Move definitions to the shared header"
  serial: 8250_dw: Don't use struct dw8250_data outside of 8250_dw
  tty: n_tty: Fix buffer offsets when lookahead is used
This commit is contained in:
Linus Torvalds 2024-06-16 11:05:47 -07:00
commit 6efc63a843
9 changed files with 64 additions and 45 deletions

View file

@ -1619,15 +1619,25 @@ static void __receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp,
else if (ldata->raw || (L_EXTPROC(tty) && !preops))
n_tty_receive_buf_raw(tty, cp, fp, count);
else if (tty->closing && !L_EXTPROC(tty)) {
if (la_count > 0)
if (la_count > 0) {
n_tty_receive_buf_closing(tty, cp, fp, la_count, true);
if (count > la_count)
n_tty_receive_buf_closing(tty, cp, fp, count - la_count, false);
cp += la_count;
if (fp)
fp += la_count;
count -= la_count;
}
if (count > 0)
n_tty_receive_buf_closing(tty, cp, fp, count, false);
} else {
if (la_count > 0)
if (la_count > 0) {
n_tty_receive_buf_standard(tty, cp, fp, la_count, true);
if (count > la_count)
n_tty_receive_buf_standard(tty, cp, fp, count - la_count, false);
cp += la_count;
if (fp)
fp += la_count;
count -= la_count;
}
if (count > 0)
n_tty_receive_buf_standard(tty, cp, fp, count, false);
flush_echoes(tty);
if (tty->ops->flush_chars)

View file

@ -55,6 +55,34 @@
#define DW_UART_QUIRK_SKIP_SET_RATE BIT(2)
#define DW_UART_QUIRK_IS_DMA_FC BIT(3)
#define DW_UART_QUIRK_APMC0D08 BIT(4)
#define DW_UART_QUIRK_CPR_VALUE BIT(5)
struct dw8250_platform_data {
u8 usr_reg;
u32 cpr_value;
unsigned int quirks;
};
struct dw8250_data {
struct dw8250_port_data data;
const struct dw8250_platform_data *pdata;
int msr_mask_on;
int msr_mask_off;
struct clk *clk;
struct clk *pclk;
struct notifier_block clk_notifier;
struct work_struct clk_work;
struct reset_control *rst;
unsigned int skip_autocfg:1;
unsigned int uart_16550_compatible:1;
};
static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
{
return container_of(data, struct dw8250_data, data);
}
static inline struct dw8250_data *clk_to_dw8250_data(struct notifier_block *nb)
{
@ -432,6 +460,10 @@ static void dw8250_prepare_rx_dma(struct uart_8250_port *p)
static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
{
unsigned int quirks = data->pdata ? data->pdata->quirks : 0;
u32 cpr_value = data->pdata ? data->pdata->cpr_value : 0;
if (quirks & DW_UART_QUIRK_CPR_VALUE)
data->data.cpr_value = cpr_value;
#ifdef CONFIG_64BIT
if (quirks & DW_UART_QUIRK_OCTEON) {
@ -714,8 +746,8 @@ static const struct dw8250_platform_data dw8250_armada_38x_data = {
static const struct dw8250_platform_data dw8250_renesas_rzn1_data = {
.usr_reg = DW_UART_USR,
.cpr_val = 0x00012f32,
.quirks = DW_UART_QUIRK_IS_DMA_FC,
.cpr_value = 0x00012f32,
.quirks = DW_UART_QUIRK_CPR_VALUE | DW_UART_QUIRK_IS_DMA_FC,
};
static const struct dw8250_platform_data dw8250_starfive_jh7100_data = {

View file

@ -242,7 +242,6 @@ static const struct serial_rs485 dw8250_rs485_supported = {
void dw8250_setup_port(struct uart_port *p)
{
struct dw8250_port_data *pd = p->private_data;
struct dw8250_data *data = to_dw8250_data(pd);
struct uart_8250_port *up = up_to_u8250p(p);
u32 reg, old_dlf;
@ -278,7 +277,7 @@ void dw8250_setup_port(struct uart_port *p)
reg = dw8250_readl_ext(p, DW_UART_CPR);
if (!reg) {
reg = data->pdata->cpr_val;
reg = pd->cpr_value;
dev_dbg(p->dev, "CPR is not available, using 0x%08x instead\n", reg);
}
if (!reg)

View file

@ -2,15 +2,10 @@
/* Synopsys DesignWare 8250 library header file. */
#include <linux/io.h>
#include <linux/notifier.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include "8250.h"
struct clk;
struct reset_control;
struct dw8250_port_data {
/* Port properties */
int line;
@ -19,42 +14,16 @@ struct dw8250_port_data {
struct uart_8250_dma dma;
/* Hardware configuration */
u32 cpr_value;
u8 dlf_size;
/* RS485 variables */
bool hw_rs485_support;
};
struct dw8250_platform_data {
u8 usr_reg;
u32 cpr_val;
unsigned int quirks;
};
struct dw8250_data {
struct dw8250_port_data data;
const struct dw8250_platform_data *pdata;
int msr_mask_on;
int msr_mask_off;
struct clk *clk;
struct clk *pclk;
struct notifier_block clk_notifier;
struct work_struct clk_work;
struct reset_control *rst;
unsigned int skip_autocfg:1;
unsigned int uart_16550_compatible:1;
};
void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, const struct ktermios *old);
void dw8250_setup_port(struct uart_port *p);
static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
{
return container_of(data, struct dw8250_data, data);
}
static inline u32 dw8250_readl_ext(struct uart_port *p, int offset)
{
if (p->iotype == UPIO_MEM32BE)

View file

@ -125,6 +125,7 @@ static int serial_pxa_probe(struct platform_device *pdev)
uart.port.iotype = UPIO_MEM32;
uart.port.regshift = 2;
uart.port.fifosize = 64;
uart.tx_loadsz = 32;
uart.dl_write = serial_pxa_dl_write;
ret = serial8250_register_8250_port(&uart);

View file

@ -1023,8 +1023,9 @@ config SERIAL_SCCNXP_CONSOLE
help
Support for console on SCCNXP serial ports.
config SERIAL_SC16IS7XX_CORE
config SERIAL_SC16IS7XX
tristate "NXP SC16IS7xx UART support"
depends on SPI_MASTER || I2C
select SERIAL_CORE
select SERIAL_SC16IS7XX_SPI if SPI_MASTER
select SERIAL_SC16IS7XX_I2C if I2C

View file

@ -75,7 +75,7 @@ obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o
obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o
obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o
obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o
obj-$(CONFIG_SERIAL_SC16IS7XX) += sc16is7xx.o
obj-$(CONFIG_SERIAL_SC16IS7XX_SPI) += sc16is7xx_spi.o
obj-$(CONFIG_SERIAL_SC16IS7XX_I2C) += sc16is7xx_i2c.o
obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o

View file

@ -622,7 +622,7 @@ static ssize_t uart_write(struct tty_struct *tty, const u8 *buf, size_t count)
return -EL3HLT;
port = uart_port_lock(state, flags);
if (WARN_ON_ONCE(!state->port.xmit_buf)) {
if (!state->port.xmit_buf) {
uart_port_unlock(port, flags);
return 0;
}

View file

@ -64,6 +64,13 @@ static int serial_port_runtime_suspend(struct device *dev)
if (port->flags & UPF_DEAD)
return 0;
/*
* Nothing to do on pm_runtime_force_suspend(), see
* DEFINE_RUNTIME_DEV_PM_OPS.
*/
if (!pm_runtime_enabled(dev))
return 0;
uart_port_lock_irqsave(port, &flags);
if (!port_dev->tx_enabled) {
uart_port_unlock_irqrestore(port, flags);