Pull tty/serial driver fixes from Greg KH: :Here are some small tty and serial driver fixes for 5.8-rc6. The largest set of patches in here is a revert of the sysrq changes that went into 5.8-rc1 but turned out to cause a noticable overhead and cpu usage. Other than that, there's a few small serial driver fixes to resolve reported issues, and finally resolving the spinlock init problem on many serial driver consoles. All of these have been in linux-next for a while with no reported issues" * tag 'tty-5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: serial: core: Initialise spin lock before use in uart_configure_port() serial: mxs-auart: add missed iounmap() in probe failure and remove serial: sh-sci: Initialize spinlock for uart console Revert "tty: xilinx_uartps: Fix missing id assignment to the console" serial: core: drop redundant sysrq checks serial: core: fix sysrq overhead regression Revert "serial: core: Refactor uart_unlock_and_check_sysrq()" tty/serial: fix serial_core.c kernel-doc warnings tty: serial: cpm_uart: Fix behaviour for non existing GPIOs
Showing the changes to include/linux (1 of 6 files). Show all
Unified · Split
| @@ -462,10 +462,104 @@ extern void uart_handle_cts_change(struct uart_port *uport, · 461 unmodified lines | ||
| 462 | 462 | extern void uart_insert_char(struct uart_port *port, unsigned int status, |
| 463 | 463 | unsigned int overrun, unsigned int ch, unsigned int flag); |
| 464 | 464 | |
| 465 | −extern int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch); | |
| 466 | −extern int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch); | |
| 467 | −extern void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long flags); | |
| 468 | −extern int uart_handle_break(struct uart_port *port); | |
| 465 | +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL | |
| 466 | +#define SYSRQ_TIMEOUT (HZ * 5) | |
| 467 | + | |
| 468 | +bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch); | |
| 469 | + | |
| 470 | +static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | |
| 471 | +{ | |
| 472 | + if (!port->sysrq) | |
| 473 | + return 0; | |
| 474 | + | |
| 475 | + if (ch && time_before(jiffies, port->sysrq)) { | |
| 476 | + if (sysrq_mask()) { | |
| 477 | + handle_sysrq(ch); | |
| 478 | + port->sysrq = 0; | |
| 479 | + return 1; | |
| 480 | + } | |
| 481 | + if (uart_try_toggle_sysrq(port, ch)) | |
| 482 | + return 1; | |
| 483 | + } | |
| 484 | + port->sysrq = 0; | |
| 485 | + | |
| 486 | + return 0; | |
| 487 | +} | |
| 488 | + | |
| 489 | +static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) | |
| 490 | +{ | |
| 491 | + if (!port->sysrq) | |
| 492 | + return 0; | |
| 493 | + | |
| 494 | + if (ch && time_before(jiffies, port->sysrq)) { | |
| 495 | + if (sysrq_mask()) { | |
| 496 | + port->sysrq_ch = ch; | |
| 497 | + port->sysrq = 0; | |
| 498 | + return 1; | |
| 499 | + } | |
| 500 | + if (uart_try_toggle_sysrq(port, ch)) | |
| 501 | + return 1; | |
| 502 | + } | |
| 503 | + port->sysrq = 0; | |
| 504 | + | |
| 505 | + return 0; | |
| 506 | +} | |
| 507 | + | |
| 508 | +static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) | |
| 509 | +{ | |
| 510 | + int sysrq_ch; | |
| 511 | + | |
| 512 | + if (!port->has_sysrq) { | |
| 513 | + spin_unlock_irqrestore(&port->lock, irqflags); | |
| 514 | + return; | |
| 515 | + } | |
| 516 | + | |
| 517 | + sysrq_ch = port->sysrq_ch; | |
| 518 | + port->sysrq_ch = 0; | |
| 519 | + | |
| 520 | + spin_unlock_irqrestore(&port->lock, irqflags); | |
| 521 | + | |
| 522 | + if (sysrq_ch) | |
| 523 | + handle_sysrq(sysrq_ch); | |
| 524 | +} | |
| 525 | +#else /* CONFIG_MAGIC_SYSRQ_SERIAL */ | |
| 526 | +static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | |
| 527 | +{ | |
| 528 | + return 0; | |
| 529 | +} | |
| 530 | +static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) | |
| 531 | +{ | |
| 532 | + return 0; | |
| 533 | +} | |
| 534 | +static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) | |
| 535 | +{ | |
| 536 | + spin_unlock_irqrestore(&port->lock, irqflags); | |
| 537 | +} | |
| 538 | +#endif /* CONFIG_MAGIC_SYSRQ_SERIAL */ | |
| 539 | + | |
| 540 | +/* | |
| 541 | + * We do the SysRQ and SAK checking like this... | |
| 542 | + */ | |
| 543 | +static inline int uart_handle_break(struct uart_port *port) | |
| 544 | +{ | |
| 545 | + struct uart_state *state = port->state; | |
| 546 | + | |
| 547 | + if (port->handle_break) | |
| 548 | + port->handle_break(port); | |
| 549 | + | |
| 550 | +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL | |
| 551 | + if (port->has_sysrq && uart_console(port)) { | |
| 552 | + if (!port->sysrq) { | |
| 553 | + port->sysrq = jiffies + SYSRQ_TIMEOUT; | |
| 554 | + return 1; | |
| 555 | + } | |
| 556 | + port->sysrq = 0; | |
| 557 | + } | |
| 558 | +#endif | |
| 559 | + if (port->flags & UPF_SAK) | |
| 560 | + do_SAK(state->port.tty); | |
| 561 | + return 0; | |
| 562 | +} | |
| 469 | 563 | |
| 470 | 564 | /* |
| 471 | 565 | * UART_ENABLE_MS - determine if port should enable modem status irqs |