Skip to content

Commit 437e878

Browse files
committed
Merge tag 'tty-5.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH: "Here are 2 tty and serial fixes for 5.0-rc2 that resolve some reported issues. The first is a simple serial driver fix for a regression that showed up in 5.0-rc1. The second one resolves a number of reported issues with the recent tty locking fixes that went into 5.0-rc1. Lots of people have tested the second one and say it resolves their issues. Both have been in linux-next with no reported issues" * tag 'tty-5.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: tty: Don't hold ldisc lock in tty_reopen() if ldisc present serial: lantiq: Do not swap register read/writes
2 parents 1dd8a3f + d3736d8 commit 437e878

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

drivers/tty/serial/lantiq.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ struct ltq_uart_port {
114114

115115
static inline void asc_update_bits(u32 clear, u32 set, void __iomem *reg)
116116
{
117-
u32 tmp = readl(reg);
117+
u32 tmp = __raw_readl(reg);
118118

119-
writel((tmp & ~clear) | set, reg);
119+
__raw_writel((tmp & ~clear) | set, reg);
120120
}
121121

122122
static inline struct
@@ -144,7 +144,7 @@ lqasc_start_tx(struct uart_port *port)
144144
static void
145145
lqasc_stop_rx(struct uart_port *port)
146146
{
147-
writel(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
147+
__raw_writel(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
148148
}
149149

150150
static int
@@ -153,11 +153,12 @@ lqasc_rx_chars(struct uart_port *port)
153153
struct tty_port *tport = &port->state->port;
154154
unsigned int ch = 0, rsr = 0, fifocnt;
155155

156-
fifocnt = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
156+
fifocnt = __raw_readl(port->membase + LTQ_ASC_FSTAT) &
157+
ASCFSTAT_RXFFLMASK;
157158
while (fifocnt--) {
158159
u8 flag = TTY_NORMAL;
159160
ch = readb(port->membase + LTQ_ASC_RBUF);
160-
rsr = (readl(port->membase + LTQ_ASC_STATE)
161+
rsr = (__raw_readl(port->membase + LTQ_ASC_STATE)
161162
& ASCSTATE_ANY) | UART_DUMMY_UER_RX;
162163
tty_flip_buffer_push(tport);
163164
port->icount.rx++;
@@ -217,7 +218,7 @@ lqasc_tx_chars(struct uart_port *port)
217218
return;
218219
}
219220

220-
while (((readl(port->membase + LTQ_ASC_FSTAT) &
221+
while (((__raw_readl(port->membase + LTQ_ASC_FSTAT) &
221222
ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) {
222223
if (port->x_char) {
223224
writeb(port->x_char, port->membase + LTQ_ASC_TBUF);
@@ -245,7 +246,7 @@ lqasc_tx_int(int irq, void *_port)
245246
unsigned long flags;
246247
struct uart_port *port = (struct uart_port *)_port;
247248
spin_lock_irqsave(&ltq_asc_lock, flags);
248-
writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
249+
__raw_writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
249250
spin_unlock_irqrestore(&ltq_asc_lock, flags);
250251
lqasc_start_tx(port);
251252
return IRQ_HANDLED;
@@ -270,7 +271,7 @@ lqasc_rx_int(int irq, void *_port)
270271
unsigned long flags;
271272
struct uart_port *port = (struct uart_port *)_port;
272273
spin_lock_irqsave(&ltq_asc_lock, flags);
273-
writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
274+
__raw_writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
274275
lqasc_rx_chars(port);
275276
spin_unlock_irqrestore(&ltq_asc_lock, flags);
276277
return IRQ_HANDLED;
@@ -280,7 +281,8 @@ static unsigned int
280281
lqasc_tx_empty(struct uart_port *port)
281282
{
282283
int status;
283-
status = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
284+
status = __raw_readl(port->membase + LTQ_ASC_FSTAT) &
285+
ASCFSTAT_TXFFLMASK;
284286
return status ? 0 : TIOCSER_TEMT;
285287
}
286288

@@ -313,12 +315,12 @@ lqasc_startup(struct uart_port *port)
313315
asc_update_bits(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
314316
port->membase + LTQ_ASC_CLC);
315317

316-
writel(0, port->membase + LTQ_ASC_PISEL);
317-
writel(
318+
__raw_writel(0, port->membase + LTQ_ASC_PISEL);
319+
__raw_writel(
318320
((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) |
319321
ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU,
320322
port->membase + LTQ_ASC_TXFCON);
321-
writel(
323+
__raw_writel(
322324
((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK)
323325
| ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU,
324326
port->membase + LTQ_ASC_RXFCON);
@@ -350,7 +352,7 @@ lqasc_startup(struct uart_port *port)
350352
goto err2;
351353
}
352354

353-
writel(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
355+
__raw_writel(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
354356
port->membase + LTQ_ASC_IRNREN);
355357
return 0;
356358

@@ -369,7 +371,7 @@ lqasc_shutdown(struct uart_port *port)
369371
free_irq(ltq_port->rx_irq, port);
370372
free_irq(ltq_port->err_irq, port);
371373

372-
writel(0, port->membase + LTQ_ASC_CON);
374+
__raw_writel(0, port->membase + LTQ_ASC_CON);
373375
asc_update_bits(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
374376
port->membase + LTQ_ASC_RXFCON);
375377
asc_update_bits(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
@@ -461,13 +463,13 @@ lqasc_set_termios(struct uart_port *port,
461463
asc_update_bits(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON);
462464

463465
/* now we can write the new baudrate into the register */
464-
writel(divisor, port->membase + LTQ_ASC_BG);
466+
__raw_writel(divisor, port->membase + LTQ_ASC_BG);
465467

466468
/* turn the baudrate generator back on */
467469
asc_update_bits(0, ASCCON_R, port->membase + LTQ_ASC_CON);
468470

469471
/* enable rx */
470-
writel(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
472+
__raw_writel(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
471473

472474
spin_unlock_irqrestore(&ltq_asc_lock, flags);
473475

@@ -578,7 +580,7 @@ lqasc_console_putchar(struct uart_port *port, int ch)
578580
return;
579581

580582
do {
581-
fifofree = (readl(port->membase + LTQ_ASC_FSTAT)
583+
fifofree = (__raw_readl(port->membase + LTQ_ASC_FSTAT)
582584
& ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
583585
} while (fifofree == 0);
584586
writeb(ch, port->membase + LTQ_ASC_TBUF);

drivers/tty/tty_io.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,8 @@ static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *
12561256
static int tty_reopen(struct tty_struct *tty)
12571257
{
12581258
struct tty_driver *driver = tty->driver;
1259-
int retval;
1259+
struct tty_ldisc *ld;
1260+
int retval = 0;
12601261

12611262
if (driver->type == TTY_DRIVER_TYPE_PTY &&
12621263
driver->subtype == PTY_TYPE_MASTER)
@@ -1268,13 +1269,18 @@ static int tty_reopen(struct tty_struct *tty)
12681269
if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
12691270
return -EBUSY;
12701271

1271-
retval = tty_ldisc_lock(tty, 5 * HZ);
1272-
if (retval)
1273-
return retval;
1272+
ld = tty_ldisc_ref_wait(tty);
1273+
if (ld) {
1274+
tty_ldisc_deref(ld);
1275+
} else {
1276+
retval = tty_ldisc_lock(tty, 5 * HZ);
1277+
if (retval)
1278+
return retval;
12741279

1275-
if (!tty->ldisc)
1276-
retval = tty_ldisc_reinit(tty, tty->termios.c_line);
1277-
tty_ldisc_unlock(tty);
1280+
if (!tty->ldisc)
1281+
retval = tty_ldisc_reinit(tty, tty->termios.c_line);
1282+
tty_ldisc_unlock(tty);
1283+
}
12781284

12791285
if (retval == 0)
12801286
tty->count++;

0 commit comments

Comments
 (0)