aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/pch_uart.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-03-21 12:44:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-03-21 12:44:10 -0700
commit3bcb0bf65c2b8d67dbe7509da8d1461ee4445db7 (patch)
treeed0506aa0429318deacaf08cbec74ccf66a441c3 /drivers/tty/serial/pch_uart.c
parente09bf86f3d53ecf4da61163d88036c4c16419d70 (diff)
parentd6c0d892b44cd16e0421909cf7f2883b9e625e4a (diff)
downloadlinux-3bcb0bf65c2b8d67dbe7509da8d1461ee4445db7.tar.gz
Merge tag 'tty-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty / serial driver updates from Greg KH: "Here is the big set of TTY/Serial driver updates and cleanups for 6.9-rc1. Included in here are: - more tty cleanups from Jiri - loads of 8250 driver cleanups from Andy - max310x driver updates - samsung serial driver updates - uart_prepare_sysrq_char() updates for many drivers - platform driver remove callback void cleanups - stm32 driver updates - other small tty/serial driver updates All of these have been in linux-next for a long time with no reported issues" * tag 'tty-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (199 commits) dt-bindings: serial: stm32: add power-domains property serial: 8250_dw: Replace ACPI device check by a quirk serial: Lock console when calling into driver before registration serial: 8250_uniphier: Switch to use uart_read_port_properties() serial: 8250_tegra: Switch to use uart_read_port_properties() serial: 8250_pxa: Switch to use uart_read_port_properties() serial: 8250_omap: Switch to use uart_read_port_properties() serial: 8250_of: Switch to use uart_read_port_properties() serial: 8250_lpc18xx: Switch to use uart_read_port_properties() serial: 8250_ingenic: Switch to use uart_read_port_properties() serial: 8250_dw: Switch to use uart_read_port_properties() serial: 8250_bcm7271: Switch to use uart_read_port_properties() serial: 8250_bcm2835aux: Switch to use uart_read_port_properties() serial: 8250_aspeed_vuart: Switch to use uart_read_port_properties() serial: port: Introduce a common helper to read properties serial: core: Add UPIO_UNKNOWN constant for unknown port type serial: core: Move struct uart_port::quirks closer to possible values serial: sh-sci: Call sci_serial_{in,out}() directly serial: core: only stop transmit when HW fifo is empty serial: pch: Use uart_prepare_sysrq_char(). ...
Diffstat (limited to 'drivers/tty/serial/pch_uart.c')
-rw-r--r--drivers/tty/serial/pch_uart.c70
1 files changed, 19 insertions, 51 deletions
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 436cc6d52a11bf..89257cddf54050 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -237,9 +237,6 @@ struct eg20t_port {
#define IRQ_NAME_SIZE 17
char irq_name[IRQ_NAME_SIZE];
-
- /* protect the eg20t_port private structure and io access to membase */
- spinlock_t lock;
};
/**
@@ -567,7 +564,7 @@ static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf,
if (uart_handle_break(port))
continue;
}
- if (uart_handle_sysrq_char(port, rbr))
+ if (uart_prepare_sysrq_char(port, rbr))
continue;
buf[i++] = rbr;
@@ -599,16 +596,14 @@ static void pch_uart_hal_set_break(struct eg20t_port *priv, int on)
iowrite8(lcr, priv->membase + UART_LCR);
}
-static int push_rx(struct eg20t_port *priv, const unsigned char *buf,
- int size)
+static void push_rx(struct eg20t_port *priv, const unsigned char *buf,
+ int size)
{
struct uart_port *port = &priv->port;
struct tty_port *tport = &port->state->port;
tty_insert_flip_string(tport, buf, size);
tty_flip_buffer_push(tport);
-
- return 0;
}
static int dma_push_rx(struct eg20t_port *priv, int size)
@@ -761,7 +756,7 @@ static int handle_rx_to(struct eg20t_port *priv)
{
struct pch_uart_buffer *buf;
int rx_size;
- int ret;
+
if (!priv->start_rx) {
pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT |
PCH_UART_HAL_RX_ERR_INT);
@@ -770,19 +765,12 @@ static int handle_rx_to(struct eg20t_port *priv)
buf = &priv->rxbuf;
do {
rx_size = pch_uart_hal_read(priv, buf->buf, buf->size);
- ret = push_rx(priv, buf->buf, rx_size);
- if (ret)
- return 0;
+ push_rx(priv, buf->buf, rx_size);
} while (rx_size == buf->size);
return PCH_UART_HANDLED_RX_INT;
}
-static int handle_rx(struct eg20t_port *priv)
-{
- return handle_rx_to(priv);
-}
-
static int dma_handle_rx(struct eg20t_port *priv)
{
struct uart_port *port = &priv->port;
@@ -1019,11 +1007,10 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
u8 lsr;
int ret = 0;
unsigned char iid;
- unsigned long flags;
int next = 1;
u8 msr;
- spin_lock_irqsave(&priv->lock, flags);
+ uart_port_lock(&priv->port);
handled = 0;
while (next) {
iid = pch_uart_hal_get_iid(priv);
@@ -1051,7 +1038,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
PCH_UART_HAL_RX_INT |
PCH_UART_HAL_RX_ERR_INT);
} else {
- ret = handle_rx(priv);
+ ret = handle_rx_to(priv);
}
break;
case PCH_UART_IID_RDR_TO: /* Received Data Ready
@@ -1083,7 +1070,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
handled |= (unsigned int)ret;
}
- spin_unlock_irqrestore(&priv->lock, flags);
+ uart_unlock_and_check_sysrq(&priv->port);
return IRQ_RETVAL(handled);
}
@@ -1194,9 +1181,9 @@ static void pch_uart_break_ctl(struct uart_port *port, int ctl)
unsigned long flags;
priv = container_of(port, struct eg20t_port, port);
- spin_lock_irqsave(&priv->lock, flags);
+ uart_port_lock_irqsave(&priv->port, &flags);
pch_uart_hal_set_break(priv, ctl);
- spin_unlock_irqrestore(&priv->lock, flags);
+ uart_port_unlock_irqrestore(&priv->port, flags);
}
/* Grab any interrupt resources and initialise any low level driver state. */
@@ -1346,8 +1333,7 @@ static void pch_uart_set_termios(struct uart_port *port,
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
- spin_lock_irqsave(&priv->lock, flags);
- uart_port_lock(port);
+ uart_port_lock_irqsave(port, &flags);
uart_update_timeout(port, termios->c_cflag, baud);
rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb);
@@ -1360,8 +1346,7 @@ static void pch_uart_set_termios(struct uart_port *port,
tty_termios_encode_baud_rate(termios, baud, baud);
out:
- uart_port_unlock(port);
- spin_unlock_irqrestore(&priv->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static const char *pch_uart_type(struct uart_port *port)
@@ -1565,27 +1550,17 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
{
struct eg20t_port *priv;
unsigned long flags;
- int priv_locked = 1;
- int port_locked = 1;
+ int locked = 1;
u8 ier;
priv = pch_uart_ports[co->index];
touch_nmi_watchdog();
- local_irq_save(flags);
- if (priv->port.sysrq) {
- /* call to uart_handle_sysrq_char already took the priv lock */
- priv_locked = 0;
- /* serial8250_handle_port() already took the port lock */
- port_locked = 0;
- } else if (oops_in_progress) {
- priv_locked = spin_trylock(&priv->lock);
- port_locked = uart_port_trylock(&priv->port);
- } else {
- spin_lock(&priv->lock);
- uart_port_lock(&priv->port);
- }
+ if (oops_in_progress)
+ locked = uart_port_trylock_irqsave(&priv->port, &flags);
+ else
+ uart_port_lock_irqsave(&priv->port, &flags);
/*
* First save the IER then disable the interrupts
@@ -1603,11 +1578,8 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
wait_for_xmitr(priv, UART_LSR_BOTH_EMPTY);
iowrite8(ier, priv->membase + UART_IER);
- if (port_locked)
- uart_port_unlock(&priv->port);
- if (priv_locked)
- spin_unlock(&priv->lock);
- local_irq_restore(flags);
+ if (locked)
+ uart_port_unlock_irqrestore(&priv->port, flags);
}
static int __init pch_console_setup(struct console *co, char *options)
@@ -1704,8 +1676,6 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
pci_enable_msi(pdev);
pci_set_master(pdev);
- spin_lock_init(&priv->lock);
-
iobase = pci_resource_start(pdev, 0);
mapbase = pci_resource_start(pdev, 1);
priv->mapbase = mapbase;
@@ -1735,8 +1705,6 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
KBUILD_MODNAME ":" PCH_UART_DRIVER_DEVICE "%d",
priv->port.line);
- spin_lock_init(&priv->port.lock);
-
pci_set_drvdata(pdev, priv);
priv->trigger_level = 1;
priv->fcr = 0;