816-tty-serial-support-layerscape.patch 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. From c35aec61e5bb0faafb2847a0d750ebd7345a4b0f Mon Sep 17 00:00:00 2001
  2. From: Yangbo Lu <[email protected]>
  3. Date: Wed, 17 Jan 2018 15:40:24 +0800
  4. Subject: [PATCH 28/30] tty: serial: support layerscape
  5. This is an integrated patch for layerscape uart support.
  6. Signed-off-by: Nikita Yushchenko <[email protected]>
  7. Signed-off-by: Yuan Yao <[email protected]>
  8. Signed-off-by: Stefan Agner <[email protected]>
  9. Signed-off-by: Yangbo Lu <[email protected]>
  10. ---
  11. drivers/tty/serial/fsl_lpuart.c | 66 ++++++++++++++++++++++++++++-------------
  12. 1 file changed, 46 insertions(+), 20 deletions(-)
  13. --- a/drivers/tty/serial/fsl_lpuart.c
  14. +++ b/drivers/tty/serial/fsl_lpuart.c
  15. @@ -231,6 +231,8 @@
  16. #define DEV_NAME "ttyLP"
  17. #define UART_NR 6
  18. +static DECLARE_BITMAP(linemap, UART_NR);
  19. +
  20. struct lpuart_port {
  21. struct uart_port port;
  22. struct clk *clk;
  23. @@ -1348,6 +1350,18 @@ lpuart_set_termios(struct uart_port *por
  24. /* ask the core to calculate the divisor */
  25. baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
  26. + /*
  27. + * Need to update the Ring buffer length according to the selected
  28. + * baud rate and restart Rx DMA path.
  29. + *
  30. + * Since timer function acqures sport->port.lock, need to stop before
  31. + * acquring same lock because otherwise del_timer_sync() can deadlock.
  32. + */
  33. + if (old && sport->lpuart_dma_rx_use) {
  34. + del_timer_sync(&sport->lpuart_timer);
  35. + lpuart_dma_rx_free(&sport->port);
  36. + }
  37. +
  38. spin_lock_irqsave(&sport->port.lock, flags);
  39. sport->port.read_status_mask = 0;
  40. @@ -1397,22 +1411,11 @@ lpuart_set_termios(struct uart_port *por
  41. /* restore control register */
  42. writeb(old_cr2, sport->port.membase + UARTCR2);
  43. - /*
  44. - * If new baud rate is set, we will also need to update the Ring buffer
  45. - * length according to the selected baud rate and restart Rx DMA path.
  46. - */
  47. - if (old) {
  48. - if (sport->lpuart_dma_rx_use) {
  49. - del_timer_sync(&sport->lpuart_timer);
  50. - lpuart_dma_rx_free(&sport->port);
  51. - }
  52. -
  53. - if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
  54. - sport->lpuart_dma_rx_use = true;
  55. + if (old && sport->lpuart_dma_rx_use) {
  56. + if (!lpuart_start_rx_dma(sport))
  57. rx_dma_timer_init(sport);
  58. - } else {
  59. + else
  60. sport->lpuart_dma_rx_use = false;
  61. - }
  62. }
  63. spin_unlock_irqrestore(&sport->port.lock, flags);
  64. @@ -1640,6 +1643,13 @@ lpuart_console_write(struct console *co,
  65. {
  66. struct lpuart_port *sport = lpuart_ports[co->index];
  67. unsigned char old_cr2, cr2;
  68. + unsigned long flags;
  69. + int locked = 1;
  70. +
  71. + if (sport->port.sysrq || oops_in_progress)
  72. + locked = spin_trylock_irqsave(&sport->port.lock, flags);
  73. + else
  74. + spin_lock_irqsave(&sport->port.lock, flags);
  75. /* first save CR2 and then disable interrupts */
  76. cr2 = old_cr2 = readb(sport->port.membase + UARTCR2);
  77. @@ -1654,6 +1664,9 @@ lpuart_console_write(struct console *co,
  78. barrier();
  79. writeb(old_cr2, sport->port.membase + UARTCR2);
  80. +
  81. + if (locked)
  82. + spin_unlock_irqrestore(&sport->port.lock, flags);
  83. }
  84. static void
  85. @@ -1661,6 +1674,13 @@ lpuart32_console_write(struct console *c
  86. {
  87. struct lpuart_port *sport = lpuart_ports[co->index];
  88. unsigned long old_cr, cr;
  89. + unsigned long flags;
  90. + int locked = 1;
  91. +
  92. + if (sport->port.sysrq || oops_in_progress)
  93. + locked = spin_trylock_irqsave(&sport->port.lock, flags);
  94. + else
  95. + spin_lock_irqsave(&sport->port.lock, flags);
  96. /* first save CR2 and then disable interrupts */
  97. cr = old_cr = lpuart32_read(sport->port.membase + UARTCTRL);
  98. @@ -1675,6 +1695,9 @@ lpuart32_console_write(struct console *c
  99. barrier();
  100. lpuart32_write(old_cr, sport->port.membase + UARTCTRL);
  101. +
  102. + if (locked)
  103. + spin_unlock_irqrestore(&sport->port.lock, flags);
  104. }
  105. /*
  106. @@ -1899,13 +1922,13 @@ static int lpuart_probe(struct platform_
  107. ret = of_alias_get_id(np, "serial");
  108. if (ret < 0) {
  109. - dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
  110. - return ret;
  111. - }
  112. - if (ret >= ARRAY_SIZE(lpuart_ports)) {
  113. - dev_err(&pdev->dev, "serial%d out of range\n", ret);
  114. - return -EINVAL;
  115. + ret = find_first_zero_bit(linemap, UART_NR);
  116. + if (ret >= UART_NR) {
  117. + dev_err(&pdev->dev, "port line is full, add device failed\n");
  118. + return ret;
  119. + }
  120. }
  121. + set_bit(ret, linemap);
  122. sport->port.line = ret;
  123. sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart");
  124. @@ -1987,6 +2010,7 @@ static int lpuart_remove(struct platform
  125. struct lpuart_port *sport = platform_get_drvdata(pdev);
  126. uart_remove_one_port(&lpuart_reg, &sport->port);
  127. + clear_bit(sport->port.line, linemap);
  128. clk_disable_unprepare(sport->clk);
  129. @@ -2071,12 +2095,10 @@ static int lpuart_resume(struct device *
  130. if (sport->lpuart_dma_rx_use) {
  131. if (sport->port.irq_wake) {
  132. - if (!lpuart_start_rx_dma(sport)) {
  133. - sport->lpuart_dma_rx_use = true;
  134. + if (!lpuart_start_rx_dma(sport))
  135. rx_dma_timer_init(sport);
  136. - } else {
  137. + else
  138. sport->lpuart_dma_rx_use = false;
  139. - }
  140. }
  141. }