Skip to content

Commit 868a9fd

Browse files
committed
Merge tag 'tty-6.5-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 for 6.5-rc1. Included in here are: - tty_audit code cleanups from Jiri - more 8250 cleanups from Ilpo - samsung_tty driver bugfixes - 8250 lock port updates - usual fsl_lpuart driver updates and fixes - other small serial driver fixes and updates, full details in the shortlog All of these have been in linux-next for a while with no reported issues" * tag 'tty-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (58 commits) tty_audit: make data of tty_audit_log() const tty_audit: make tty pointers in exposed functions const tty_audit: make icanon a bool tty_audit: invert the condition in tty_audit_log() tty_audit: use kzalloc() in tty_audit_buf_alloc() tty_audit: use TASK_COMM_LEN for task comm Revert "8250: add support for ASIX devices with a FIFO bug" serial: atmel: don't enable IRQs prematurely tty: serial: Add Nuvoton ma35d1 serial driver support tty: serial: fsl_lpuart: add earlycon for imx8ulp platform tty: serial: imx: fix rs485 rx after tx selftests: tty: add selftest for tty timestamp updates tty: tty_io: update timestamps on all device nodes tty: fix hang on tty device with no_room set serial: core: fix -EPROBE_DEFER handling in init serial: 8250_omap: Use force_suspend and resume for system suspend tty: serial: samsung_tty: Use abs() to simplify some code tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() when iterating clk tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() in case of error serial: 8250: Apply FSL workarounds also without SERIAL_8250_CONSOLE ...
2 parents db9c6d1 + e534755 commit 868a9fd

52 files changed

Lines changed: 2280 additions & 425 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

arch/mips/alchemy/common/platform.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
5151
#define PORT(_base, _irq) \
5252
{ \
5353
.mapbase = _base, \
54+
.mapsize = 0x1000, \
5455
.irq = _irq, \
5556
.regshift = 2, \
56-
.iotype = UPIO_AU, \
5757
.flags = UPF_SKIP_TEST | UPF_IOREMAP | \
5858
UPF_FIXED_TYPE, \
5959
.type = PORT_16550A, \
@@ -124,8 +124,14 @@ static void __init alchemy_setup_uarts(int ctype)
124124
au1xx0_uart_device.dev.platform_data = ports;
125125

126126
/* Fill up uartclk. */
127-
for (s = 0; s < c; s++)
127+
for (s = 0; s < c; s++) {
128128
ports[s].uartclk = uartclk;
129+
if (au_platform_setup(&ports[s]) < 0) {
130+
kfree(ports);
131+
printk(KERN_INFO "Alchemy: missing support for UARTs\n");
132+
return;
133+
}
134+
}
129135
if (platform_device_register(&au1xx0_uart_device))
130136
printk(KERN_INFO "Alchemy: failed to register UARTs\n");
131137
}

arch/powerpc/kernel/legacy_serial.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -508,12 +508,16 @@ static void __init fixup_port_irq(int index,
508508

509509
port->irq = virq;
510510

511-
#ifdef CONFIG_SERIAL_8250_FSL
512-
if (of_device_is_compatible(np, "fsl,ns16550")) {
513-
port->handle_irq = fsl8250_handle_irq;
514-
port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
511+
if (IS_ENABLED(CONFIG_SERIAL_8250) &&
512+
of_device_is_compatible(np, "fsl,ns16550")) {
513+
if (IS_REACHABLE(CONFIG_SERIAL_8250_FSL)) {
514+
port->handle_irq = fsl8250_handle_irq;
515+
port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
516+
} else {
517+
pr_warn_once("Not activating Freescale specific workaround for device %pOFP\n",
518+
np);
519+
}
515520
}
516-
#endif
517521
}
518522

519523
static void __init fixup_port_pio(int index,

drivers/tty/n_tty.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ static void n_tty_kick_worker(struct tty_struct *tty)
203203
struct n_tty_data *ldata = tty->disc_data;
204204

205205
/* Did the input worker stop? Restart it */
206-
if (unlikely(ldata->no_room)) {
207-
ldata->no_room = 0;
206+
if (unlikely(READ_ONCE(ldata->no_room))) {
207+
WRITE_ONCE(ldata->no_room, 0);
208208

209209
WARN_RATELIMIT(tty->port->itty == NULL,
210210
"scheduling with invalid itty\n");
@@ -1697,7 +1697,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
16971697
if (overflow && room < 0)
16981698
ldata->read_head--;
16991699
room = overflow;
1700-
ldata->no_room = flow && !room;
1700+
WRITE_ONCE(ldata->no_room, flow && !room);
17011701
} else
17021702
overflow = 0;
17031703

@@ -1728,6 +1728,17 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
17281728
} else
17291729
n_tty_check_throttle(tty);
17301730

1731+
if (unlikely(ldata->no_room)) {
1732+
/*
1733+
* Barrier here is to ensure to read the latest read_tail in
1734+
* chars_in_buffer() and to make sure that read_tail is not loaded
1735+
* before ldata->no_room is set.
1736+
*/
1737+
smp_mb();
1738+
if (!chars_in_buffer(tty))
1739+
n_tty_kick_worker(tty);
1740+
}
1741+
17311742
up_read(&tty->termios_rwsem);
17321743

17331744
return rcvd;
@@ -2281,8 +2292,14 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
22812292
if (time)
22822293
timeout = time;
22832294
}
2284-
if (old_tail != ldata->read_tail)
2295+
if (old_tail != ldata->read_tail) {
2296+
/*
2297+
* Make sure no_room is not read in n_tty_kick_worker()
2298+
* before setting ldata->read_tail in copy_from_read_buf().
2299+
*/
2300+
smp_mb();
22852301
n_tty_kick_worker(tty);
2302+
}
22862303
up_read(&tty->termios_rwsem);
22872304

22882305
remove_wait_queue(&tty->read_wait, &wait);

drivers/tty/serial/8250/8250.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ struct serial8250_config {
9191
#define UART_BUG_TXEN BIT(1) /* UART has buggy TX IIR status */
9292
#define UART_BUG_NOMSR BIT(2) /* UART has buggy MSR status bits (Au1x00) */
9393
#define UART_BUG_THRE BIT(3) /* UART has buggy THRE reassertion */
94-
#define UART_BUG_PARITY BIT(4) /* UART mishandles parity if FIFO enabled */
9594
#define UART_BUG_TXRACE BIT(5) /* UART Tx fails to set remote DR */
9695

9796

@@ -167,18 +166,21 @@ static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,
167166

168167
void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
169168

170-
static inline int serial_dl_read(struct uart_8250_port *up)
169+
static inline u32 serial_dl_read(struct uart_8250_port *up)
171170
{
172171
return up->dl_read(up);
173172
}
174173

175-
static inline void serial_dl_write(struct uart_8250_port *up, int value)
174+
static inline void serial_dl_write(struct uart_8250_port *up, u32 value)
176175
{
177176
up->dl_write(up, value);
178177
}
179178

180179
static inline bool serial8250_set_THRI(struct uart_8250_port *up)
181180
{
181+
/* Port locked to synchronize UART_IER access against the console. */
182+
lockdep_assert_held_once(&up->port.lock);
183+
182184
if (up->ier & UART_IER_THRI)
183185
return false;
184186
up->ier |= UART_IER_THRI;
@@ -188,6 +190,9 @@ static inline bool serial8250_set_THRI(struct uart_8250_port *up)
188190

189191
static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
190192
{
193+
/* Port locked to synchronize UART_IER access against the console. */
194+
lockdep_assert_held_once(&up->port.lock);
195+
191196
if (!(up->ier & UART_IER_THRI))
192197
return false;
193198
up->ier &= ~UART_IER_THRI;

drivers/tty/serial/8250/8250_aspeed_vuart.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ static void __aspeed_vuart_set_throttle(struct uart_8250_port *up,
275275
{
276276
unsigned char irqs = UART_IER_RLSI | UART_IER_RDI;
277277

278+
/* Port locked to synchronize UART_IER access against the console. */
279+
lockdep_assert_held_once(&up->port.lock);
280+
278281
up->ier &= ~irqs;
279282
if (!throttle)
280283
up->ier |= irqs;

drivers/tty/serial/8250/8250_bcm7271.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,9 +605,13 @@ static int brcmuart_startup(struct uart_port *port)
605605
/*
606606
* Disable the Receive Data Interrupt because the DMA engine
607607
* will handle this.
608+
*
609+
* Synchronize UART_IER access against the console.
608610
*/
611+
spin_lock_irq(&port->lock);
609612
up->ier &= ~UART_IER_RDI;
610613
serial_port_out(port, UART_IER, up->ier);
614+
spin_unlock_irq(&port->lock);
611615

612616
priv->tx_running = false;
613617
priv->dma.rx_dma = NULL;

drivers/tty/serial/8250/8250_core.c

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,34 @@ static inline void serial8250_apply_quirks(struct uart_8250_port *up)
488488
up->port.quirks |= skip_txen_test ? UPQ_NO_TXEN_TEST : 0;
489489
}
490490

491+
static struct uart_8250_port *serial8250_setup_port(int index)
492+
{
493+
struct uart_8250_port *up;
494+
495+
if (index >= UART_NR)
496+
return NULL;
497+
498+
up = &serial8250_ports[index];
499+
up->port.line = index;
500+
501+
serial8250_init_port(up);
502+
if (!base_ops)
503+
base_ops = up->port.ops;
504+
up->port.ops = &univ8250_port_ops;
505+
506+
timer_setup(&up->timer, serial8250_timeout, 0);
507+
508+
up->ops = &univ8250_driver_ops;
509+
510+
if (IS_ENABLED(CONFIG_ALPHA_JENSEN) ||
511+
(IS_ENABLED(CONFIG_ALPHA_GENERIC) && alpha_jensen()))
512+
up->port.set_mctrl = alpha_jensen_set_mctrl;
513+
514+
serial8250_set_defaults(up);
515+
516+
return up;
517+
}
518+
491519
static void __init serial8250_isa_init_ports(void)
492520
{
493521
struct uart_8250_port *up;
@@ -501,26 +529,13 @@ static void __init serial8250_isa_init_ports(void)
501529
if (nr_uarts > UART_NR)
502530
nr_uarts = UART_NR;
503531

504-
for (i = 0; i < nr_uarts; i++) {
505-
struct uart_8250_port *up = &serial8250_ports[i];
506-
struct uart_port *port = &up->port;
507-
508-
port->line = i;
509-
serial8250_init_port(up);
510-
if (!base_ops)
511-
base_ops = port->ops;
512-
port->ops = &univ8250_port_ops;
513-
514-
timer_setup(&up->timer, serial8250_timeout, 0);
515-
516-
up->ops = &univ8250_driver_ops;
517-
518-
if (IS_ENABLED(CONFIG_ALPHA_JENSEN) ||
519-
(IS_ENABLED(CONFIG_ALPHA_GENERIC) && alpha_jensen()))
520-
port->set_mctrl = alpha_jensen_set_mctrl;
521-
522-
serial8250_set_defaults(up);
523-
}
532+
/*
533+
* Set up initial isa ports based on nr_uart module param, or else
534+
* default to CONFIG_SERIAL_8250_RUNTIME_UARTS. Note that we do not
535+
* need to increase nr_uarts when setting up the initial isa ports.
536+
*/
537+
for (i = 0; i < nr_uarts; i++)
538+
serial8250_setup_port(i);
524539

525540
/* chain base port ops to support Remote Supervisor Adapter */
526541
univ8250_port_ops = *base_ops;
@@ -586,16 +601,29 @@ static void univ8250_console_write(struct console *co, const char *s,
586601

587602
static int univ8250_console_setup(struct console *co, char *options)
588603
{
604+
struct uart_8250_port *up;
589605
struct uart_port *port;
590-
int retval;
606+
int retval, i;
591607

592608
/*
593609
* Check whether an invalid uart number has been specified, and
594610
* if so, search for the first available port that does have
595611
* console support.
596612
*/
597-
if (co->index >= nr_uarts)
613+
if (co->index >= UART_NR)
598614
co->index = 0;
615+
616+
/*
617+
* If the console is past the initial isa ports, init more ports up to
618+
* co->index as needed and increment nr_uarts accordingly.
619+
*/
620+
for (i = nr_uarts; i <= co->index; i++) {
621+
up = serial8250_setup_port(i);
622+
if (!up)
623+
return -ENODEV;
624+
nr_uarts++;
625+
}
626+
599627
port = &serial8250_ports[co->index].port;
600628
/* link port to console */
601629
port->cons = co;
@@ -822,12 +850,16 @@ static int serial8250_probe(struct platform_device *dev)
822850
uart.port.iotype = p->iotype;
823851
uart.port.flags = p->flags;
824852
uart.port.mapbase = p->mapbase;
853+
uart.port.mapsize = p->mapsize;
825854
uart.port.hub6 = p->hub6;
826855
uart.port.has_sysrq = p->has_sysrq;
827856
uart.port.private_data = p->private_data;
828857
uart.port.type = p->type;
858+
uart.bugs = p->bugs;
829859
uart.port.serial_in = p->serial_in;
830860
uart.port.serial_out = p->serial_out;
861+
uart.dl_read = p->dl_read;
862+
uart.dl_write = p->dl_write;
831863
uart.port.handle_irq = p->handle_irq;
832864
uart.port.handle_break = p->handle_break;
833865
uart.port.set_termios = p->set_termios;
@@ -990,12 +1022,24 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
9901022
mutex_lock(&serial_mutex);
9911023

9921024
uart = serial8250_find_match_or_unused(&up->port);
993-
if (uart && uart->port.type != PORT_8250_CIR) {
1025+
if (!uart) {
1026+
/*
1027+
* If the port is past the initial isa ports, initialize a new
1028+
* port and increment nr_uarts accordingly.
1029+
*/
1030+
uart = serial8250_setup_port(nr_uarts);
1031+
if (!uart)
1032+
goto unlock;
1033+
nr_uarts++;
1034+
}
1035+
1036+
if (uart->port.type != PORT_8250_CIR) {
9941037
struct mctrl_gpios *gpios;
9951038

9961039
if (uart->port.dev)
9971040
uart_remove_one_port(&serial8250_reg, &uart->port);
9981041

1042+
uart->port.ctrl_id = up->port.ctrl_id;
9991043
uart->port.iobase = up->port.iobase;
10001044
uart->port.membase = up->port.membase;
10011045
uart->port.irq = up->port.irq;
@@ -1120,6 +1164,7 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
11201164
}
11211165
}
11221166

1167+
unlock:
11231168
mutex_unlock(&serial_mutex);
11241169

11251170
return ret;

drivers/tty/serial/8250/8250_early.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636

3737
static unsigned int serial8250_early_in(struct uart_port *port, int offset)
3838
{
39-
int reg_offset = offset;
4039
offset <<= port->regshift;
4140

4241
switch (port->iotype) {
@@ -50,16 +49,13 @@ static unsigned int serial8250_early_in(struct uart_port *port, int offset)
5049
return ioread32be(port->membase + offset);
5150
case UPIO_PORT:
5251
return inb(port->iobase + offset);
53-
case UPIO_AU:
54-
return port->serial_in(port, reg_offset);
5552
default:
5653
return 0;
5754
}
5855
}
5956

6057
static void serial8250_early_out(struct uart_port *port, int offset, int value)
6158
{
62-
int reg_offset = offset;
6359
offset <<= port->regshift;
6460

6561
switch (port->iotype) {
@@ -78,9 +74,6 @@ static void serial8250_early_out(struct uart_port *port, int offset, int value)
7874
case UPIO_PORT:
7975
outb(value, port->iobase + offset);
8076
break;
81-
case UPIO_AU:
82-
port->serial_out(port, reg_offset, value);
83-
break;
8477
}
8578
}
8679

@@ -199,17 +192,3 @@ OF_EARLYCON_DECLARE(omap8250, "ti,omap3-uart", early_omap8250_setup);
199192
OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup);
200193

201194
#endif
202-
203-
#ifdef CONFIG_SERIAL_8250_RT288X
204-
205-
static int __init early_au_setup(struct earlycon_device *dev, const char *opt)
206-
{
207-
dev->port.serial_in = au_serial_in;
208-
dev->port.serial_out = au_serial_out;
209-
dev->port.iotype = UPIO_AU;
210-
dev->con->write = early_serial8250_write;
211-
return 0;
212-
}
213-
OF_EARLYCON_DECLARE(palmchip, "ralink,rt2880-uart", early_au_setup);
214-
215-
#endif

drivers/tty/serial/8250/8250_em.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,12 @@ static void serial8250_em_serial_out(struct uart_port *p, int offset, int value)
139139
}
140140
}
141141

142-
static int serial8250_em_serial_dl_read(struct uart_8250_port *up)
142+
static u32 serial8250_em_serial_dl_read(struct uart_8250_port *up)
143143
{
144144
return serial_in(up, UART_DLL_EM) | serial_in(up, UART_DLM_EM) << 8;
145145
}
146146

147-
static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)
147+
static void serial8250_em_serial_dl_write(struct uart_8250_port *up, u32 value)
148148
{
149149
serial_out(up, UART_DLL_EM, value & 0xff);
150150
serial_out(up, UART_DLM_EM, value >> 8 & 0xff);

0 commit comments

Comments
 (0)