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