summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2018-11-21 13:21:16 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2018-11-21 13:21:16 +1100
commit5a24bb1489c54cdd648413022a55b6662ea08438 (patch)
treec824b60668af7d4d771658691924ce17f7d8572a /drivers
parent3536788e656c342be5396a65cc06f191000eae59 (diff)
parentc17a1ca14cbba5585df67544711b6d04bcc8e240 (diff)
Merge remote-tracking branch 'tty/tty-next'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/Kconfig8
-rw-r--r--drivers/char/ttyprintk.c4
-rw-r--r--drivers/tty/serial/8250/8250_aspeed_vuart.c6
-rw-r--r--drivers/tty/serial/8250/8250_fsl.c6
-rw-r--r--drivers/tty/serial/8250/8250_omap.c6
-rw-r--r--drivers/tty/serial/8250/8250_port.c8
-rw-r--r--drivers/tty/serial/8250/Kconfig1
-rw-r--r--drivers/tty/serial/amba-pl011.c2
-rw-r--r--drivers/tty/serial/fsl_lpuart.c6
-rw-r--r--drivers/tty/serial/lantiq.c145
-rw-r--r--drivers/tty/serial/pch_uart.c3
-rw-r--r--drivers/tty/serial/pic32_uart.c1
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c64
-rw-r--r--drivers/tty/serial/serial-tegra.c10
-rw-r--r--drivers/tty/serial/sh-sci.c4
-rw-r--r--drivers/tty/serial/uartlite.c88
-rw-r--r--drivers/tty/serial/xilinx_uartps.c1
17 files changed, 221 insertions, 142 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 9d03b2ff5df6..2e2ffe7010aa 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -66,6 +66,14 @@ config TTY_PRINTK
If unsure, say N.
+config TTY_PRINTK_LEVEL
+ depends on TTY_PRINTK
+ int "ttyprintk log level (1-7)"
+ range 1 7
+ default "6"
+ help
+ Printk log level to use for ttyprintk messages.
+
config PRINTER
tristate "Parallel printer support"
depends on PARPORT
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index 67549ce88cc9..88808dbba486 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -37,6 +37,8 @@ static struct ttyprintk_port tpk_port;
*/
#define TPK_STR_SIZE 508 /* should be bigger then max expected line length */
#define TPK_MAX_ROOM 4096 /* we could assume 4K for instance */
+#define TPK_PREFIX KERN_SOH __stringify(CONFIG_TTY_PRINTK_LEVEL)
+
static int tpk_curr;
static char tpk_buffer[TPK_STR_SIZE + 4];
@@ -45,7 +47,7 @@ static void tpk_flush(void)
{
if (tpk_curr > 0) {
tpk_buffer[tpk_curr] = '\0';
- pr_info("[U] %s\n", tpk_buffer);
+ printk(TPK_PREFIX "[U] %s\n", tpk_buffer);
tpk_curr = 0;
}
}
diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c
index 435bec40dee6..0438d9a905ce 100644
--- a/drivers/tty/serial/8250/8250_aspeed_vuart.c
+++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c
@@ -5,6 +5,10 @@
* Copyright (C) 2016 Jeremy Kerr <jk@ozlabs.org>, IBM Corp.
* Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
*/
+#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of_address.h>
@@ -293,7 +297,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
if (lsr & UART_LSR_THRE)
serial8250_tx_chars(up);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_unlock_and_check_sysrq(port, flags);
return 1;
}
diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
index 6640a4c7ddd1..ff3dcaea5d93 100644
--- a/drivers/tty/serial/8250/8250_fsl.c
+++ b/drivers/tty/serial/8250/8250_fsl.c
@@ -1,4 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
+#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
@@ -54,7 +58,7 @@ int fsl8250_handle_irq(struct uart_port *port)
serial8250_tx_chars(up);
up->lsr_saved_flags = orig_lsr;
- spin_unlock_irqrestore(&up->port.lock, flags);
+ uart_unlock_and_check_sysrq(&up->port, flags);
return 1;
}
EXPORT_SYMBOL_GPL(fsl8250_handle_irq);
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index a019286f8bb6..ad7ba7d0f28d 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -8,6 +8,10 @@
*
*/
+#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
@@ -1085,7 +1089,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
}
}
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_unlock_and_check_sysrq(port, flags);
serial8250_rpm_put(up);
return 1;
}
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index f776b3eafb96..c39482b96111 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1755,7 +1755,7 @@ void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
else if (lsr & UART_LSR_FE)
flag = TTY_FRAME;
}
- if (uart_handle_sysrq_char(port, ch))
+ if (uart_prepare_sysrq_char(port, ch))
return;
uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
@@ -1897,7 +1897,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE))
serial8250_tx_chars(up);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_unlock_and_check_sysrq(port, flags);
return 1;
}
EXPORT_SYMBOL_GPL(serial8250_handle_irq);
@@ -3258,9 +3258,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
serial8250_rpm_get(up);
- if (port->sysrq)
- locked = 0;
- else if (oops_in_progress)
+ if (oops_in_progress)
locked = spin_trylock_irqsave(&port->lock, flags);
else
spin_lock_irqsave(&port->lock, flags);
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 15c2c5463835..d7737dca0e48 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -484,6 +484,7 @@ config SERIAL_8250_PXA
config SERIAL_OF_PLATFORM
tristate "Devicetree based probing for 8250 ports"
depends on SERIAL_8250 && OF
+ default SERIAL_8250
help
This option is used for all 8250 compatible serial ports that
are probed through devicetree, including Open Firmware based
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index ebd33c0232e6..89ade213a1a9 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2780,6 +2780,7 @@ static struct platform_driver arm_sbsa_uart_platform_driver = {
.name = "sbsa-uart",
.of_match_table = of_match_ptr(sbsa_uart_of_match),
.acpi_match_table = ACPI_PTR(sbsa_uart_acpi_match),
+ .suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_AMBA_PL011),
},
};
@@ -2808,6 +2809,7 @@ static struct amba_driver pl011_driver = {
.drv = {
.name = "uart-pl011",
.pm = &pl011_dev_pm_ops,
+ .suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_AMBA_PL011),
},
.id_table = pl011_ids,
.probe = pl011_probe,
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 00c220e4f43c..241a48e5052c 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1479,6 +1479,8 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
else
cr1 &= ~UARTCR1_PT;
}
+ } else {
+ cr1 &= ~UARTCR1_PE;
}
/* ask the core to calculate the divisor */
@@ -1682,7 +1684,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
ctrl &= ~UARTCTRL_PE;
ctrl |= UARTCTRL_M;
} else {
- ctrl |= UARTCR1_PE;
+ ctrl |= UARTCTRL_PE;
if ((termios->c_cflag & CSIZE) == CS8)
ctrl |= UARTCTRL_M;
if (termios->c_cflag & PARODD)
@@ -1690,6 +1692,8 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
else
ctrl &= ~UARTCTRL_PT;
}
+ } else {
+ ctrl &= ~UARTCTRL_PE;
}
/* ask the core to calculate the divisor */
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c
index 044128277248..e052b69ceb98 100644
--- a/drivers/tty/serial/lantiq.c
+++ b/drivers/tty/serial/lantiq.c
@@ -8,24 +8,23 @@
* Copyright (C) 2010 Thomas Langer, <thomas.langer@lantiq.com>
*/
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
+#include <linux/clk.h>
#include <linux/console.h>
-#include <linux/sysrq.h>
#include <linux/device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/lantiq.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/gpio.h>
-
-#include <lantiq_soc.h>
+#include <linux/of_platform.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
+#include <linux/sysrq.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
#define PORT_LTQ_ASC 111
#define MAXPORTS 2
@@ -105,7 +104,7 @@ static DEFINE_SPINLOCK(ltq_asc_lock);
struct ltq_uart_port {
struct uart_port port;
/* clock used to derive divider */
- struct clk *fpiclk;
+ struct clk *freqclk;
/* clock gating of the ASC core */
struct clk *clk;
unsigned int tx_irq;
@@ -113,6 +112,13 @@ struct ltq_uart_port {
unsigned int err_irq;
};
+static inline void asc_update_bits(u32 clear, u32 set, void __iomem *reg)
+{
+ u32 tmp = readl(reg);
+
+ writel((tmp & ~clear) | set, reg);
+}
+
static inline struct
ltq_uart_port *to_ltq_uart_port(struct uart_port *port)
{
@@ -138,7 +144,7 @@ lqasc_start_tx(struct uart_port *port)
static void
lqasc_stop_rx(struct uart_port *port)
{
- ltq_w32(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
+ writel(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
}
static int
@@ -147,11 +153,11 @@ lqasc_rx_chars(struct uart_port *port)
struct tty_port *tport = &port->state->port;
unsigned int ch = 0, rsr = 0, fifocnt;
- fifocnt = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
+ fifocnt = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
while (fifocnt--) {
u8 flag = TTY_NORMAL;
- ch = ltq_r8(port->membase + LTQ_ASC_RBUF);
- rsr = (ltq_r32(port->membase + LTQ_ASC_STATE)
+ ch = readb(port->membase + LTQ_ASC_RBUF);
+ rsr = (readl(port->membase + LTQ_ASC_STATE)
& ASCSTATE_ANY) | UART_DUMMY_UER_RX;
tty_flip_buffer_push(tport);
port->icount.rx++;
@@ -163,16 +169,16 @@ lqasc_rx_chars(struct uart_port *port)
if (rsr & ASCSTATE_ANY) {
if (rsr & ASCSTATE_PE) {
port->icount.parity++;
- ltq_w32_mask(0, ASCWHBSTATE_CLRPE,
+ asc_update_bits(0, ASCWHBSTATE_CLRPE,
port->membase + LTQ_ASC_WHBSTATE);
} else if (rsr & ASCSTATE_FE) {
port->icount.frame++;
- ltq_w32_mask(0, ASCWHBSTATE_CLRFE,
+ asc_update_bits(0, ASCWHBSTATE_CLRFE,
port->membase + LTQ_ASC_WHBSTATE);
}
if (rsr & ASCSTATE_ROE) {
port->icount.overrun++;
- ltq_w32_mask(0, ASCWHBSTATE_CLRROE,
+ asc_update_bits(0, ASCWHBSTATE_CLRROE,
port->membase + LTQ_ASC_WHBSTATE);
}
@@ -211,10 +217,10 @@ lqasc_tx_chars(struct uart_port *port)
return;
}
- while (((ltq_r32(port->membase + LTQ_ASC_FSTAT) &
+ while (((readl(port->membase + LTQ_ASC_FSTAT) &
ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) {
if (port->x_char) {
- ltq_w8(port->x_char, port->membase + LTQ_ASC_TBUF);
+ writeb(port->x_char, port->membase + LTQ_ASC_TBUF);
port->icount.tx++;
port->x_char = 0;
continue;
@@ -223,7 +229,7 @@ lqasc_tx_chars(struct uart_port *port)
if (uart_circ_empty(xmit))
break;
- ltq_w8(port->state->xmit.buf[port->state->xmit.tail],
+ writeb(port->state->xmit.buf[port->state->xmit.tail],
port->membase + LTQ_ASC_TBUF);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
@@ -239,7 +245,7 @@ lqasc_tx_int(int irq, void *_port)
unsigned long flags;
struct uart_port *port = (struct uart_port *)_port;
spin_lock_irqsave(&ltq_asc_lock, flags);
- ltq_w32(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
+ writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
spin_unlock_irqrestore(&ltq_asc_lock, flags);
lqasc_start_tx(port);
return IRQ_HANDLED;
@@ -252,7 +258,7 @@ lqasc_err_int(int irq, void *_port)
struct uart_port *port = (struct uart_port *)_port;
spin_lock_irqsave(&ltq_asc_lock, flags);
/* clear any pending interrupts */
- ltq_w32_mask(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE |
+ asc_update_bits(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE |
ASCWHBSTATE_CLRROE, port->membase + LTQ_ASC_WHBSTATE);
spin_unlock_irqrestore(&ltq_asc_lock, flags);
return IRQ_HANDLED;
@@ -264,7 +270,7 @@ lqasc_rx_int(int irq, void *_port)
unsigned long flags;
struct uart_port *port = (struct uart_port *)_port;
spin_lock_irqsave(&ltq_asc_lock, flags);
- ltq_w32(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
+ writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
lqasc_rx_chars(port);
spin_unlock_irqrestore(&ltq_asc_lock, flags);
return IRQ_HANDLED;
@@ -274,7 +280,7 @@ static unsigned int
lqasc_tx_empty(struct uart_port *port)
{
int status;
- status = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
+ status = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
return status ? 0 : TIOCSER_TEMT;
}
@@ -301,18 +307,18 @@ lqasc_startup(struct uart_port *port)
int retval;
if (!IS_ERR(ltq_port->clk))
- clk_enable(ltq_port->clk);
- port->uartclk = clk_get_rate(ltq_port->fpiclk);
+ clk_prepare_enable(ltq_port->clk);
+ port->uartclk = clk_get_rate(ltq_port->freqclk);
- ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
+ asc_update_bits(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
port->membase + LTQ_ASC_CLC);
- ltq_w32(0, port->membase + LTQ_ASC_PISEL);
- ltq_w32(
+ writel(0, port->membase + LTQ_ASC_PISEL);
+ writel(
((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) |
ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU,
port->membase + LTQ_ASC_TXFCON);
- ltq_w32(
+ writel(
((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK)
| ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU,
port->membase + LTQ_ASC_RXFCON);
@@ -320,7 +326,7 @@ lqasc_startup(struct uart_port *port)
* setting enable bits
*/
wmb();
- ltq_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN |
+ asc_update_bits(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN |
ASCCON_ROEN, port->membase + LTQ_ASC_CON);
retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
@@ -344,7 +350,7 @@ lqasc_startup(struct uart_port *port)
goto err2;
}
- ltq_w32(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
+ writel(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
port->membase + LTQ_ASC_IRNREN);
return 0;
@@ -363,13 +369,13 @@ lqasc_shutdown(struct uart_port *port)
free_irq(ltq_port->rx_irq, port);
free_irq(ltq_port->err_irq, port);
- ltq_w32(0, port->membase + LTQ_ASC_CON);
- ltq_w32_mask(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
+ writel(0, port->membase + LTQ_ASC_CON);
+ asc_update_bits(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
port->membase + LTQ_ASC_RXFCON);
- ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
+ asc_update_bits(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
port->membase + LTQ_ASC_TXFCON);
if (!IS_ERR(ltq_port->clk))
- clk_disable(ltq_port->clk);
+ clk_disable_unprepare(ltq_port->clk);
}
static void
@@ -438,7 +444,7 @@ lqasc_set_termios(struct uart_port *port,
spin_lock_irqsave(&ltq_asc_lock, flags);
/* set up CON */
- ltq_w32_mask(0, con, port->membase + LTQ_ASC_CON);
+ asc_update_bits(0, con, port->membase + LTQ_ASC_CON);
/* Set baud rate - take a divider of 2 into account */
baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
@@ -446,22 +452,22 @@ lqasc_set_termios(struct uart_port *port,
divisor = divisor / 2 - 1;
/* disable the baudrate generator */
- ltq_w32_mask(ASCCON_R, 0, port->membase + LTQ_ASC_CON);
+ asc_update_bits(ASCCON_R, 0, port->membase + LTQ_ASC_CON);
/* make sure the fractional divider is off */
- ltq_w32_mask(ASCCON_FDE, 0, port->membase + LTQ_ASC_CON);
+ asc_update_bits(ASCCON_FDE, 0, port->membase + LTQ_ASC_CON);
/* set up to use divisor of 2 */
- ltq_w32_mask(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON);
+ asc_update_bits(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON);
/* now we can write the new baudrate into the register */
- ltq_w32(divisor, port->membase + LTQ_ASC_BG);
+ writel(divisor, port->membase + LTQ_ASC_BG);
/* turn the baudrate generator back on */
- ltq_w32_mask(0, ASCCON_R, port->membase + LTQ_ASC_CON);
+ asc_update_bits(0, ASCCON_R, port->membase + LTQ_ASC_CON);
/* enable rx */
- ltq_w32(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
+ writel(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
spin_unlock_irqrestore(&ltq_asc_lock, flags);
@@ -572,10 +578,10 @@ lqasc_console_putchar(struct uart_port *port, int ch)
return;
do {
- fifofree = (ltq_r32(port->membase + LTQ_ASC_FSTAT)
+ fifofree = (readl(port->membase + LTQ_ASC_FSTAT)
& ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
} while (fifofree == 0);
- ltq_w8(ch, port->membase + LTQ_ASC_TBUF);
+ writeb(ch, port->membase + LTQ_ASC_TBUF);
}
static void lqasc_serial_port_write(struct uart_port *port, const char *s,
@@ -623,9 +629,9 @@ lqasc_console_setup(struct console *co, char *options)
port = &ltq_port->port;
if (!IS_ERR(ltq_port->clk))
- clk_enable(ltq_port->clk);
+ clk_prepare_enable(ltq_port->clk);
- port->uartclk = clk_get_rate(ltq_port->fpiclk);
+ port->uartclk = clk_get_rate(ltq_port->freqclk);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -688,7 +694,7 @@ lqasc_probe(struct platform_device *pdev)
struct ltq_uart_port *ltq_port;
struct uart_port *port;
struct resource *mmres, irqres[3];
- int line = 0;
+ int line;
int ret;
mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -699,9 +705,20 @@ lqasc_probe(struct platform_device *pdev)
return -ENODEV;
}
- /* check if this is the console port */
- if (mmres->start != CPHYSADDR(LTQ_EARLY_ASC))
- line = 1;
+ /* get serial id */
+ line = of_alias_get_id(node, "serial");
+ if (line < 0) {
+ if (IS_ENABLED(CONFIG_LANTIQ)) {
+ if (mmres->start == CPHYSADDR(LTQ_EARLY_ASC))
+ line = 0;
+ else
+ line = 1;
+ } else {
+ dev_err(&pdev->dev, "failed to get alias id, errno %d\n",
+ line);
+ return line;
+ }
+ }
if (lqasc_port[line]) {
dev_err(&pdev->dev, "port %d already allocated\n", line);
@@ -726,14 +743,22 @@ lqasc_probe(struct platform_device *pdev)
port->irq = irqres[0].start;
port->mapbase = mmres->start;
- ltq_port->fpiclk = clk_get_fpi();
- if (IS_ERR(ltq_port->fpiclk)) {
+ if (IS_ENABLED(CONFIG_LANTIQ) && !IS_ENABLED(CONFIG_COMMON_CLK))
+ ltq_port->freqclk = clk_get_fpi();
+ else
+ ltq_port->freqclk = devm_clk_get(&pdev->dev, "freq");
+
+
+ if (IS_ERR(ltq_port->freqclk)) {
pr_err("failed to get fpi clk\n");
return -ENOENT;
}
/* not all asc ports have clock gates, lets ignore the return code */
- ltq_port->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ENABLED(CONFIG_LANTIQ) && !IS_ENABLED(CONFIG_COMMON_CLK))
+ ltq_port->clk = clk_get(&pdev->dev, NULL);
+ else
+ ltq_port->clk = devm_clk_get(&pdev->dev, "asc");
ltq_port->tx_irq = irqres[0].start;
ltq_port->rx_irq = irqres[1].start;
@@ -759,7 +784,7 @@ static struct platform_driver lqasc_driver = {
},
};
-int __init
+static int __init
init_lqasc(void)
{
int ret;
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index cb85002a10d8..9ed121f08a54 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -933,7 +933,6 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
struct scatterlist *sg;
int nent;
int fifo_size;
- int tx_empty;
struct dma_async_tx_descriptor *desc;
int num;
int i;
@@ -958,11 +957,9 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
}
fifo_size = max(priv->fifo_size, 1);
- tx_empty = 1;
if (pop_tx_x(priv, xmit->buf)) {
pch_uart_hal_write(priv, xmit->buf, 1);
port->icount.tx++;
- tx_empty = 0;
fifo_size--;
}
diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c
index fd80d999308d..0bdf1687983f 100644
--- a/drivers/tty/serial/pic32_uart.c
+++ b/drivers/tty/serial/pic32_uart.c
@@ -919,6 +919,7 @@ static struct platform_driver pic32_uart_platform_driver = {
.driver = {
.name = PIC32_DEV_NAME,
.of_match_table = of_match_ptr(pic32_serial_dt_ids),
+ .suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_PIC32),
},
};
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index d3b5261ee80a..ac001c07399b 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1,6 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
+#if defined(CONFIG_SERIAL_QCOM_GENI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+# define SUPPORT_SYSRQ
+#endif
+
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
@@ -89,9 +93,9 @@
#define MAX_LOOPBACK_CFG 3
#ifdef CONFIG_CONSOLE_POLL
-#define RX_BYTES_PW 1
+#define CONSOLE_RX_BYTES_PW 1
#else
-#define RX_BYTES_PW 4
+#define CONSOLE_RX_BYTES_PW 4
#endif
struct qcom_geni_serial_port {
@@ -162,8 +166,7 @@ static struct qcom_geni_serial_port qcom_geni_uart_ports[GENI_UART_PORTS] = {
static ssize_t loopback_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
+ struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
return snprintf(buf, sizeof(u32), "%d\n", port->loopback);
}
@@ -172,8 +175,7 @@ static ssize_t loopback_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t size)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
+ struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
u32 loopback;
if (kstrtoint(buf, 0, &loopback) || loopback > MAX_LOOPBACK_CFG) {
@@ -495,7 +497,8 @@ static int handle_rx_console(struct uart_port *uport, u32 bytes, bool drop)
continue;
}
- sysrq = uart_handle_sysrq_char(uport, buf[c]);
+ sysrq = uart_prepare_sysrq_char(uport, buf[c]);
+
if (!sysrq)
tty_insert_flip_char(tport, buf[c], TTY_NORMAL);
}
@@ -804,7 +807,8 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
qcom_geni_serial_handle_rx(uport, drop_rx);
out_unlock:
- spin_unlock_irqrestore(&uport->lock, flags);
+ uart_unlock_and_check_sysrq(uport, flags);
+
return IRQ_HANDLED;
}
@@ -853,11 +857,13 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
unsigned int rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT;
u32 proto;
- if (uart_console(uport))
+ if (uart_console(uport)) {
port->tx_bytes_pw = 1;
- else
+ port->rx_bytes_pw = CONSOLE_RX_BYTES_PW;
+ } else {
port->tx_bytes_pw = 4;
- port->rx_bytes_pw = RX_BYTES_PW;
+ port->rx_bytes_pw = 4;
+ }
proto = geni_se_read_proto(&port->se);
if (proto != GENI_SE_UART) {
@@ -1322,49 +1328,25 @@ static int qcom_geni_serial_remove(struct platform_device *pdev)
return 0;
}
-static int __maybe_unused qcom_geni_serial_sys_suspend_noirq(struct device *dev)
+static int __maybe_unused qcom_geni_serial_sys_suspend(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
- if (uart_console(uport)) {
- uart_suspend_port(uport->private_data, uport);
- } else {
- struct uart_state *state = uport->state;
- /*
- * If the port is open, deny system suspend.
- */
- if (state->pm_state == UART_PM_STATE_ON)
- return -EBUSY;
- }
-
- return 0;
+ return uart_suspend_port(uport->private_data, uport);
}
-static int __maybe_unused qcom_geni_serial_sys_resume_noirq(struct device *dev)
+static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
- if (uart_console(uport) &&
- console_suspend_enabled && uport->suspended) {
- uart_resume_port(uport->private_data, uport);
- /*
- * uart_suspend_port() invokes port shutdown which in turn
- * frees the irq. uart_resume_port invokes port startup which
- * performs request_irq. The request_irq auto-enables the IRQ.
- * In addition, resume_noirq implicitly enables the IRQ and
- * leads to an unbalanced IRQ enable warning. Disable the IRQ
- * before returning so that the warning is suppressed.
- */
- disable_irq(uport->irq);
- }
- return 0;
+ return uart_resume_port(uport->private_data, uport);
}
static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_sys_suspend_noirq,
- qcom_geni_serial_sys_resume_noirq)
+ SET_SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_sys_suspend,
+ qcom_geni_serial_sys_resume)
};
static const struct of_device_id qcom_geni_serial_match_table[] = {
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
index af2a29cfbbe9..d5269aaaf9b2 100644
--- a/drivers/tty/serial/serial-tegra.c
+++ b/drivers/tty/serial/serial-tegra.c
@@ -746,7 +746,7 @@ static void tegra_uart_stop_rx(struct uart_port *u)
if (!tup->rx_in_progress)
return;
- tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */
+ tegra_uart_wait_sym_time(tup, 1); /* wait one character interval */
ier = tup->ier_shadow;
ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE |
@@ -887,7 +887,7 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup)
*
* EORD is different interrupt than RX_TIMEOUT - RX_TIMEOUT occurs when
* the DATA is sitting in the FIFO and couldn't be transferred to the
- * DMA as the DMA size alignment(4 bytes) is not met. EORD will be
+ * DMA as the DMA size alignment (4 bytes) is not met. EORD will be
* triggered when there is a pause of the incomming data stream for 4
* characters long.
*
@@ -1079,7 +1079,7 @@ static void tegra_uart_set_termios(struct uart_port *u,
if (tup->rts_active)
set_rts(tup, false);
- /* Clear all interrupts as configuration is going to be change */
+ /* Clear all interrupts as configuration is going to be changed */
tegra_uart_write(tup, tup->ier_shadow | UART_IER_RDI, UART_IER);
tegra_uart_read(tup, UART_IER);
tegra_uart_write(tup, 0, UART_IER);
@@ -1165,10 +1165,10 @@ static void tegra_uart_set_termios(struct uart_port *u,
/* update the port timeout based on new settings */
uart_update_timeout(u, termios->c_cflag, baud);
- /* Make sure all write has completed */
+ /* Make sure all writes have completed */
tegra_uart_read(tup, UART_IER);
- /* Reenable interrupt */
+ /* Re-enable interrupt */
tegra_uart_write(tup, tup->ier_shadow, UART_IER);
tegra_uart_read(tup, UART_IER);
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index cc56cb3b3eca..8146d9cef0cb 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1693,7 +1693,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
* of whether the I_IXOFF is set, otherwise, how is the interrupt
* to be disabled?
*/
- sci_receive_chars(ptr);
+ sci_receive_chars(port);
return IRQ_HANDLED;
}
@@ -1749,7 +1749,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
} else {
sci_handle_fifo_overrun(port);
if (!s->chan_rx)
- sci_receive_chars(ptr);
+ sci_receive_chars(port);
}
sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c
index f0344adc86db..4a7989df5ff5 100644
--- a/drivers/tty/serial/uartlite.c
+++ b/drivers/tty/serial/uartlite.c
@@ -22,6 +22,7 @@
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/clk.h>
+#include <linux/pm_runtime.h>
#define ULITE_NAME "ttyUL"
#define ULITE_MAJOR 204
@@ -54,6 +55,7 @@
#define ULITE_CONTROL_RST_TX 0x01
#define ULITE_CONTROL_RST_RX 0x02
#define ULITE_CONTROL_IE 0x10
+#define UART_AUTOSUSPEND_TIMEOUT 3000
/* Static pointer to console port */
#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
@@ -63,6 +65,7 @@ static struct uart_port *console_port;
struct uartlite_data {
const struct uartlite_reg_ops *reg_ops;
struct clk *clk;
+ struct uart_driver *ulite_uart_driver;
};
struct uartlite_reg_ops {
@@ -390,12 +393,12 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
static void ulite_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
- struct uartlite_data *pdata = port->private_data;
-
- if (!state)
- clk_enable(pdata->clk);
- else
- clk_disable(pdata->clk);
+ if (!state) {
+ pm_runtime_get_sync(port->dev);
+ } else {
+ pm_runtime_mark_last_busy(port->dev);
+ pm_runtime_put_autosuspend(port->dev);
+ }
}
#ifdef CONFIG_CONSOLE_POLL
@@ -691,10 +694,11 @@ static int ulite_assign(struct device *dev, int id, u32 base, int irq,
static int ulite_release(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
+ struct uartlite_data *pdata = port->private_data;
int rc = 0;
if (port) {
- rc = uart_remove_one_port(&ulite_uart_driver, port);
+ rc = uart_remove_one_port(pdata->ulite_uart_driver, port);
dev_set_drvdata(dev, NULL);
port->mapbase = 0;
}
@@ -711,9 +715,10 @@ static int ulite_release(struct device *dev)
static int __maybe_unused ulite_suspend(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
+ struct uartlite_data *pdata = port->private_data;
if (port)
- uart_suspend_port(&ulite_uart_driver, port);
+ uart_suspend_port(pdata->ulite_uart_driver, port);
return 0;
}
@@ -727,18 +732,40 @@ static int __maybe_unused ulite_suspend(struct device *dev)
static int __maybe_unused ulite_resume(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
+ struct uartlite_data *pdata = port->private_data;
if (port)
- uart_resume_port(&ulite_uart_driver, port);
+ uart_resume_port(pdata->ulite_uart_driver, port);
return 0;
}
+static int __maybe_unused ulite_runtime_suspend(struct device *dev)
+{
+ struct uart_port *port = dev_get_drvdata(dev);
+ struct uartlite_data *pdata = port->private_data;
+
+ clk_disable(pdata->clk);
+ return 0;
+};
+
+static int __maybe_unused ulite_runtime_resume(struct device *dev)
+{
+ struct uart_port *port = dev_get_drvdata(dev);
+ struct uartlite_data *pdata = port->private_data;
+
+ clk_enable(pdata->clk);
+ return 0;
+}
/* ---------------------------------------------------------------------
* Platform bus binding
*/
-static SIMPLE_DEV_PM_OPS(ulite_pm_ops, ulite_suspend, ulite_resume);
+static const struct dev_pm_ops ulite_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ulite_suspend, ulite_resume)
+ SET_RUNTIME_PM_OPS(ulite_runtime_suspend,
+ ulite_runtime_resume, NULL)
+};
#if defined(CONFIG_OF)
/* Match table for of_platform binding */
@@ -763,6 +790,22 @@ static int ulite_probe(struct platform_device *pdev)
if (prop)
id = be32_to_cpup(prop);
#endif
+ if (id < 0) {
+ /* Look for a serialN alias */
+ id = of_alias_get_id(pdev->dev.of_node, "serial");
+ if (id < 0)
+ id = 0;
+ }
+
+ if (!ulite_uart_driver.state) {
+ dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
+ ret = uart_register_driver(&ulite_uart_driver);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register driver\n");
+ return ret;
+ }
+ }
+
pdata = devm_kzalloc(&pdev->dev, sizeof(struct uartlite_data),
GFP_KERNEL);
if (!pdata)
@@ -788,24 +831,22 @@ static int ulite_probe(struct platform_device *pdev)
pdata->clk = NULL;
}
+ pdata->ulite_uart_driver = &ulite_uart_driver;
ret = clk_prepare_enable(pdata->clk);
if (ret) {
dev_err(&pdev->dev, "Failed to prepare clock\n");
return ret;
}
- if (!ulite_uart_driver.state) {
- dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
- ret = uart_register_driver(&ulite_uart_driver);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to register driver\n");
- return ret;
- }
- }
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata);
- clk_disable(pdata->clk);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_put_autosuspend(&pdev->dev);
return ret;
}
@@ -814,9 +855,14 @@ static int ulite_remove(struct platform_device *pdev)
{
struct uart_port *port = dev_get_drvdata(&pdev->dev);
struct uartlite_data *pdata = port->private_data;
+ int rc;
- clk_disable_unprepare(pdata->clk);
- return ulite_release(&pdev->dev);
+ clk_unprepare(pdata->clk);
+ rc = ulite_release(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ return rc;
}
/* work with hotplug and coldplug */
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 57c66d2c3471..379242b96790 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1719,6 +1719,7 @@ static struct platform_driver cdns_uart_platform_driver = {
.name = CDNS_UART_NAME,
.of_match_table = cdns_uart_of_match,
.pm = &cdns_uart_dev_pm_ops,
+ .suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_XILINX_PS_UART),
},
};