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
Unified · Split
| @@ -1215,7 +1215,12 @@ static int cpm_uart_init_port(struct device_node *np, · 1214 unmodified lines | ||
| 1215 | 1215 | |
| 1216 | 1216 | pinfo->gpios[i] = NULL; |
| 1217 | 1217 | |
| 1218 | − gpiod = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS); | |
| 1218 | + gpiod = devm_gpiod_get_index_optional(dev, NULL, i, GPIOD_ASIS); | |
| 1219 | + | |
| 1220 | + if (IS_ERR(gpiod)) { | |
| 1221 | + ret = PTR_ERR(gpiod); | |
| 1222 | + goto out_irq; | |
| 1223 | + } | |
| 1219 | 1224 | |
| 1220 | 1225 | if (gpiod) { |
| 1221 | 1226 | if (i == GPIO_RTS || i == GPIO_DTR) |
| @@ -1237,6 +1242,8 @@ static int cpm_uart_init_port(struct device_node *np, · 15 unmodified lines | ||
| 1237 | 1242 | |
| 1238 | 1243 | return cpm_uart_request_port(&pinfo->port); |
| 1239 | 1244 | |
| 1245 | +out_irq: | |
| 1246 | + irq_dispose_mapping(pinfo->port.irq); | |
| 1240 | 1247 | out_pram: |
| 1241 | 1248 | cpm_uart_unmap_pram(pinfo, pram); |
| 1242 | 1249 | out_mem: |
| @@ -1698,21 +1698,21 @@ static int mxs_auart_probe(struct platform_device *pdev) · 1697 unmodified lines | ||
| 1698 | 1698 | irq = platform_get_irq(pdev, 0); |
| 1699 | 1699 | if (irq < 0) { |
| 1700 | 1700 | ret = irq; |
| 1701 | − goto out_disable_clks; | |
| 1701 | + goto out_iounmap; | |
| 1702 | 1702 | } |
| 1703 | 1703 | |
| 1704 | 1704 | s->port.irq = irq; |
| 1705 | 1705 | ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0, |
| 1706 | 1706 | dev_name(&pdev->dev), s); |
| 1707 | 1707 | if (ret) |
| 1708 | − goto out_disable_clks; | |
| 1708 | + goto out_iounmap; | |
| 1709 | 1709 | |
| 1710 | 1710 | platform_set_drvdata(pdev, s); |
| 1711 | 1711 | |
| 1712 | 1712 | ret = mxs_auart_init_gpios(s, &pdev->dev); |
| 1713 | 1713 | if (ret) { |
| 1714 | 1714 | dev_err(&pdev->dev, "Failed to initialize GPIOs.\n"); |
| 1715 | − goto out_disable_clks; | |
| 1715 | + goto out_iounmap; | |
| 1716 | 1716 | } |
| 1717 | 1717 | |
| 1718 | 1718 | /* |
| @@ -1720,7 +1720,7 @@ static int mxs_auart_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 1720 | 1720 | */ |
| 1721 | 1721 | ret = mxs_auart_request_gpio_irq(s); |
| 1722 | 1722 | if (ret) |
| 1723 | − goto out_disable_clks; | |
| 1723 | + goto out_iounmap; | |
| 1724 | 1724 | |
| 1725 | 1725 | auart_port[s->port.line] = s; |
| 1726 | 1726 | |
| @@ -1746,6 +1746,9 @@ out_free_qpio_irq: · 19 unmodified lines | ||
| 1746 | 1746 | mxs_auart_free_gpio_irq(s); |
| 1747 | 1747 | auart_port[pdev->id] = NULL; |
| 1748 | 1748 | |
| 1749 | +out_iounmap: | |
| 1750 | + iounmap(s->port.membase); | |
| 1751 | + | |
| 1749 | 1752 | out_disable_clks: |
| 1750 | 1753 | if (is_asm9260_auart(s)) { |
| 1751 | 1754 | clk_disable_unprepare(s->clk); |
| @@ -1761,6 +1764,7 @@ static int mxs_auart_remove(struct platform_device *pdev) · 9 unmodified lines | ||
| 1761 | 1764 | uart_remove_one_port(&auart_driver, &s->port); |
| 1762 | 1765 | auart_port[pdev->id] = NULL; |
| 1763 | 1766 | mxs_auart_free_gpio_irq(s); |
| 1767 | + iounmap(s->port.membase); | |
| 1764 | 1768 | if (is_asm9260_auart(s)) { |
| 1765 | 1769 | clk_disable_unprepare(s->clk); |
| 1766 | 1770 | clk_disable_unprepare(s->clk_ahb); |
| @@ -41,8 +41,6 @@ static struct lock_class_key port_lock_key; · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) |
| 43 | 43 | |
| 44 | −#define SYSRQ_TIMEOUT (HZ * 5) | |
| 45 | − | |
| 46 | 44 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
| 47 | 45 | struct ktermios *old_termios); |
| 48 | 46 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); |
| @@ -1916,6 +1914,12 @@ static inline bool uart_console_enabled(struct uart_port *port) · 1867 unmodified lines | ||
| 1916 | 1914 | return uart_console(port) && (port->cons->flags & CON_ENABLED); |
| 1917 | 1915 | } |
| 1918 | 1916 | |
| 1917 | +static void __uart_port_spin_lock_init(struct uart_port *port) | |
| 1918 | +{ | |
| 1919 | + spin_lock_init(&port->lock); | |
| 1920 | + lockdep_set_class(&port->lock, &port_lock_key); | |
| 1921 | +} | |
| 1922 | + | |
| 1919 | 1923 | /* |
| 1920 | 1924 | * Ensure that the serial console lock is initialised early. |
| 1921 | 1925 | * If this port is a console, then the spinlock is already initialised. |
| @@ -1925,8 +1929,7 @@ static inline void uart_port_spin_lock_init(struct uart_port *port) · 3 unmodified lines | ||
| 1925 | 1929 | if (uart_console(port)) |
| 1926 | 1930 | return; |
| 1927 | 1931 | |
| 1928 | − spin_lock_init(&port->lock); | |
| 1929 | − lockdep_set_class(&port->lock, &port_lock_key); | |
| 1932 | + __uart_port_spin_lock_init(port); | |
| 1930 | 1933 | } |
| 1931 | 1934 | |
| 1932 | 1935 | #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL) |
| @@ -2372,6 +2375,13 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, · 439 unmodified lines | ||
| 2372 | 2375 | /* Power up port for set_mctrl() */ |
| 2373 | 2376 | uart_change_pm(state, UART_PM_STATE_ON); |
| 2374 | 2377 | |
| 2378 | + /* | |
| 2379 | + * If this driver supports console, and it hasn't been | |
| 2380 | + * successfully registered yet, initialise spin lock for it. | |
| 2381 | + */ | |
| 2382 | + if (port->cons && !(port->cons->flags & CON_ENABLED)) | |
| 2383 | + __uart_port_spin_lock_init(port); | |
| 2384 | + | |
| 2375 | 2385 | /* |
| 2376 | 2386 | * Ensure that the modem control lines are de-activated. |
| 2377 | 2387 | * keep the DTR setting that is set in uart_set_options() |
| @@ -3163,7 +3173,7 @@ static DECLARE_WORK(sysrq_enable_work, uart_sysrq_on); · 785 unmodified lines | ||
| 3163 | 3173 | * Returns false if @ch is out of enabling sequence and should be |
| 3164 | 3174 | * handled some other way, true if @ch was consumed. |
| 3165 | 3175 | */ |
| 3166 | −static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch) | |
| 3176 | +bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch) | |
| 3167 | 3177 | { |
| 3168 | 3178 | int sysrq_toggle_seq_len = strlen(sysrq_toggle_seq); |
| 3169 | 3179 | |
| @@ -3186,99 +3196,9 @@ static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch) · 16 unmodified lines | ||
| 3186 | 3196 | port->sysrq = 0; |
| 3187 | 3197 | return true; |
| 3188 | 3198 | } |
| 3189 | −#else | |
| 3190 | −static inline bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch) | |
| 3191 | −{ | |
| 3192 | − return false; | |
| 3193 | −} | |
| 3199 | +EXPORT_SYMBOL_GPL(uart_try_toggle_sysrq); | |
| 3194 | 3200 | #endif |
| 3195 | 3201 | |
| 3196 | −int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | |
| 3197 | −{ | |
| 3198 | − if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL)) | |
| 3199 | − return 0; | |
| 3200 | − | |
| 3201 | − if (!port->has_sysrq || !port->sysrq) | |
| 3202 | − return 0; | |
| 3203 | − | |
| 3204 | − if (ch && time_before(jiffies, port->sysrq)) { | |
| 3205 | − if (sysrq_mask()) { | |
| 3206 | − handle_sysrq(ch); | |
| 3207 | − port->sysrq = 0; | |
| 3208 | − return 1; | |
| 3209 | − } | |
| 3210 | − if (uart_try_toggle_sysrq(port, ch)) | |
| 3211 | − return 1; | |
| 3212 | − } | |
| 3213 | − port->sysrq = 0; | |
| 3214 | − | |
| 3215 | − return 0; | |
| 3216 | −} | |
| 3217 | −EXPORT_SYMBOL_GPL(uart_handle_sysrq_char); | |
| 3218 | − | |
| 3219 | −int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) | |
| 3220 | −{ | |
| 3221 | − if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL)) | |
| 3222 | − return 0; | |
| 3223 | − | |
| 3224 | − if (!port->has_sysrq || !port->sysrq) | |
| 3225 | − return 0; | |
| 3226 | − | |
| 3227 | − if (ch && time_before(jiffies, port->sysrq)) { | |
| 3228 | − if (sysrq_mask()) { | |
| 3229 | − port->sysrq_ch = ch; | |
| 3230 | − port->sysrq = 0; | |
| 3231 | − return 1; | |
| 3232 | − } | |
| 3233 | − if (uart_try_toggle_sysrq(port, ch)) | |
| 3234 | − return 1; | |
| 3235 | − } | |
| 3236 | − port->sysrq = 0; | |
| 3237 | − | |
| 3238 | − return 0; | |
| 3239 | −} | |
| 3240 | −EXPORT_SYMBOL_GPL(uart_prepare_sysrq_char); | |
| 3241 | − | |
| 3242 | −void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long flags) | |
| 3243 | −__releases(&port->lock) | |
| 3244 | −{ | |
| 3245 | − if (port->has_sysrq) { | |
| 3246 | − int sysrq_ch = port->sysrq_ch; | |
| 3247 | − | |
| 3248 | − port->sysrq_ch = 0; | |
| 3249 | − spin_unlock_irqrestore(&port->lock, flags); | |
| 3250 | − if (sysrq_ch) | |
| 3251 | − handle_sysrq(sysrq_ch); | |
| 3252 | − } else { | |
| 3253 | − spin_unlock_irqrestore(&port->lock, flags); | |
| 3254 | − } | |
| 3255 | −} | |
| 3256 | −EXPORT_SYMBOL_GPL(uart_unlock_and_check_sysrq); | |
| 3257 | − | |
| 3258 | −/* | |
| 3259 | − * We do the SysRQ and SAK checking like this... | |
| 3260 | − */ | |
| 3261 | −int uart_handle_break(struct uart_port *port) | |
| 3262 | −{ | |
| 3263 | − struct uart_state *state = port->state; | |
| 3264 | − | |
| 3265 | − if (port->handle_break) | |
| 3266 | − port->handle_break(port); | |
| 3267 | − | |
| 3268 | − if (port->has_sysrq && uart_console(port)) { | |
| 3269 | − if (!port->sysrq) { | |
| 3270 | − port->sysrq = jiffies + SYSRQ_TIMEOUT; | |
| 3271 | − return 1; | |
| 3272 | − } | |
| 3273 | − port->sysrq = 0; | |
| 3274 | − } | |
| 3275 | − | |
| 3276 | − if (port->flags & UPF_SAK) | |
| 3277 | − do_SAK(state->port.tty); | |
| 3278 | − return 0; | |
| 3279 | −} | |
| 3280 | −EXPORT_SYMBOL_GPL(uart_handle_break); | |
| 3281 | − | |
| 3282 | 3202 | EXPORT_SYMBOL(uart_write_wakeup); |
| 3283 | 3203 | EXPORT_SYMBOL(uart_register_driver); |
| 3284 | 3204 | EXPORT_SYMBOL(uart_unregister_driver); |
| @@ -3289,8 +3209,7 @@ EXPORT_SYMBOL(uart_remove_one_port); · 4 unmodified lines | ||
| 3289 | 3209 | |
| 3290 | 3210 | /** |
| 3291 | 3211 | * uart_get_rs485_mode() - retrieve rs485 properties for given uart |
| 3292 | − * @dev: uart device | |
| 3293 | − * @rs485conf: output parameter | |
| 3212 | + * @port: uart device's target port | |
| 3294 | 3213 | * |
| 3295 | 3214 | * This function implements the device tree binding described in |
| 3296 | 3215 | * Documentation/devicetree/bindings/serial/rs485.txt. |
| @@ -3301,6 +3301,9 @@ static int sci_probe_single(struct platform_device *dev, · 3300 unmodified lines | ||
| 3301 | 3301 | sciport->port.flags |= UPF_HARD_FLOW; |
| 3302 | 3302 | } |
| 3303 | 3303 | |
| 3304 | + if (sci_uart_driver.cons->index == sciport->port.line) | |
| 3305 | + spin_lock_init(&sciport->port.lock); | |
| 3306 | + | |
| 3304 | 3307 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); |
| 3305 | 3308 | if (ret) { |
| 3306 | 3309 | sci_cleanup_single(sciport); |
| @@ -1465,7 +1465,6 @@ static int cdns_uart_probe(struct platform_device *pdev) · 1464 unmodified lines | ||
| 1465 | 1465 | cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS; |
| 1466 | 1466 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
| 1467 | 1467 | cdns_uart_uart_driver.cons = &cdns_uart_console; |
| 1468 | − cdns_uart_console.index = id; | |
| 1469 | 1468 | #endif |
| 1470 | 1469 | |
| 1471 | 1470 | rc = uart_register_driver(&cdns_uart_uart_driver); |
| @@ -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 |