diff options
Diffstat (limited to 'drivers/tty/serial/efm32-uart.c')
-rw-r--r-- | drivers/tty/serial/efm32-uart.c | 830 |
1 files changed, 830 insertions, 0 deletions
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c new file mode 100644 index 000000000000..615e46470491 --- /dev/null +++ b/drivers/tty/serial/efm32-uart.c | |||
@@ -0,0 +1,830 @@ | |||
1 | #if defined(CONFIG_SERIAL_EFM32_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
2 | #define SUPPORT_SYSRQ | ||
3 | #endif | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/io.h> | ||
8 | #include <linux/platform_device.h> | ||
9 | #include <linux/console.h> | ||
10 | #include <linux/sysrq.h> | ||
11 | #include <linux/serial_core.h> | ||
12 | #include <linux/tty_flip.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_device.h> | ||
17 | |||
18 | #include <linux/platform_data/efm32-uart.h> | ||
19 | |||
20 | #define DRIVER_NAME "efm32-uart" | ||
21 | #define DEV_NAME "ttyefm" | ||
22 | |||
23 | #define UARTn_CTRL 0x00 | ||
24 | #define UARTn_CTRL_SYNC 0x0001 | ||
25 | #define UARTn_CTRL_TXBIL 0x1000 | ||
26 | |||
27 | #define UARTn_FRAME 0x04 | ||
28 | #define UARTn_FRAME_DATABITS__MASK 0x000f | ||
29 | #define UARTn_FRAME_DATABITS(n) ((n) - 3) | ||
30 | #define UARTn_FRAME_PARITY_NONE 0x0000 | ||
31 | #define UARTn_FRAME_PARITY_EVEN 0x0200 | ||
32 | #define UARTn_FRAME_PARITY_ODD 0x0300 | ||
33 | #define UARTn_FRAME_STOPBITS_HALF 0x0000 | ||
34 | #define UARTn_FRAME_STOPBITS_ONE 0x1000 | ||
35 | #define UARTn_FRAME_STOPBITS_TWO 0x3000 | ||
36 | |||
37 | #define UARTn_CMD 0x0c | ||
38 | #define UARTn_CMD_RXEN 0x0001 | ||
39 | #define UARTn_CMD_RXDIS 0x0002 | ||
40 | #define UARTn_CMD_TXEN 0x0004 | ||
41 | #define UARTn_CMD_TXDIS 0x0008 | ||
42 | |||
43 | #define UARTn_STATUS 0x10 | ||
44 | #define UARTn_STATUS_TXENS 0x0002 | ||
45 | #define UARTn_STATUS_TXC 0x0020 | ||
46 | #define UARTn_STATUS_TXBL 0x0040 | ||
47 | #define UARTn_STATUS_RXDATAV 0x0080 | ||
48 | |||
49 | #define UARTn_CLKDIV 0x14 | ||
50 | |||
51 | #define UARTn_RXDATAX 0x18 | ||
52 | #define UARTn_RXDATAX_RXDATA__MASK 0x01ff | ||
53 | #define UARTn_RXDATAX_PERR 0x4000 | ||
54 | #define UARTn_RXDATAX_FERR 0x8000 | ||
55 | /* | ||
56 | * This is a software only flag used for ignore_status_mask and | ||
57 | * read_status_mask! It's used for breaks that the hardware doesn't report | ||
58 | * explicitly. | ||
59 | */ | ||
60 | #define SW_UARTn_RXDATAX_BERR 0x2000 | ||
61 | |||
62 | #define UARTn_TXDATA 0x34 | ||
63 | |||
64 | #define UARTn_IF 0x40 | ||
65 | #define UARTn_IF_TXC 0x0001 | ||
66 | #define UARTn_IF_TXBL 0x0002 | ||
67 | #define UARTn_IF_RXDATAV 0x0004 | ||
68 | #define UARTn_IF_RXOF 0x0010 | ||
69 | |||
70 | #define UARTn_IFS 0x44 | ||
71 | #define UARTn_IFC 0x48 | ||
72 | #define UARTn_IEN 0x4c | ||
73 | |||
74 | #define UARTn_ROUTE 0x54 | ||
75 | #define UARTn_ROUTE_LOCATION__MASK 0x0700 | ||
76 | #define UARTn_ROUTE_LOCATION(n) (((n) << 8) & UARTn_ROUTE_LOCATION__MASK) | ||
77 | #define UARTn_ROUTE_RXPEN 0x0001 | ||
78 | #define UARTn_ROUTE_TXPEN 0x0002 | ||
79 | |||
80 | struct efm32_uart_port { | ||
81 | struct uart_port port; | ||
82 | unsigned int txirq; | ||
83 | struct clk *clk; | ||
84 | }; | ||
85 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) | ||
86 | #define efm_debug(efm_port, format, arg...) \ | ||
87 | dev_dbg(efm_port->port.dev, format, ##arg) | ||
88 | |||
89 | static void efm32_uart_write32(struct efm32_uart_port *efm_port, | ||
90 | u32 value, unsigned offset) | ||
91 | { | ||
92 | writel_relaxed(value, efm_port->port.membase + offset); | ||
93 | } | ||
94 | |||
95 | static u32 efm32_uart_read32(struct efm32_uart_port *efm_port, | ||
96 | unsigned offset) | ||
97 | { | ||
98 | return readl_relaxed(efm_port->port.membase + offset); | ||
99 | } | ||
100 | |||
101 | static unsigned int efm32_uart_tx_empty(struct uart_port *port) | ||
102 | { | ||
103 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
104 | u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
105 | |||
106 | if (status & UARTn_STATUS_TXC) | ||
107 | return TIOCSER_TEMT; | ||
108 | else | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static void efm32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
113 | { | ||
114 | /* sorry, neither handshaking lines nor loop functionallity */ | ||
115 | } | ||
116 | |||
117 | static unsigned int efm32_uart_get_mctrl(struct uart_port *port) | ||
118 | { | ||
119 | /* sorry, no handshaking lines available */ | ||
120 | return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; | ||
121 | } | ||
122 | |||
123 | static void efm32_uart_stop_tx(struct uart_port *port) | ||
124 | { | ||
125 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
126 | u32 ien = efm32_uart_read32(efm_port, UARTn_IEN); | ||
127 | |||
128 | efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); | ||
129 | ien &= ~(UARTn_IF_TXC | UARTn_IF_TXBL); | ||
130 | efm32_uart_write32(efm_port, ien, UARTn_IEN); | ||
131 | } | ||
132 | |||
133 | static void efm32_uart_tx_chars(struct efm32_uart_port *efm_port) | ||
134 | { | ||
135 | struct uart_port *port = &efm_port->port; | ||
136 | struct circ_buf *xmit = &port->state->xmit; | ||
137 | |||
138 | while (efm32_uart_read32(efm_port, UARTn_STATUS) & | ||
139 | UARTn_STATUS_TXBL) { | ||
140 | if (port->x_char) { | ||
141 | port->icount.tx++; | ||
142 | efm32_uart_write32(efm_port, port->x_char, | ||
143 | UARTn_TXDATA); | ||
144 | port->x_char = 0; | ||
145 | continue; | ||
146 | } | ||
147 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) { | ||
148 | port->icount.tx++; | ||
149 | efm32_uart_write32(efm_port, xmit->buf[xmit->tail], | ||
150 | UARTn_TXDATA); | ||
151 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
152 | } else | ||
153 | break; | ||
154 | } | ||
155 | |||
156 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
157 | uart_write_wakeup(port); | ||
158 | |||
159 | if (!port->x_char && uart_circ_empty(xmit) && | ||
160 | efm32_uart_read32(efm_port, UARTn_STATUS) & | ||
161 | UARTn_STATUS_TXC) | ||
162 | efm32_uart_stop_tx(port); | ||
163 | } | ||
164 | |||
165 | static void efm32_uart_start_tx(struct uart_port *port) | ||
166 | { | ||
167 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
168 | u32 ien; | ||
169 | |||
170 | efm32_uart_write32(efm_port, | ||
171 | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IFC); | ||
172 | ien = efm32_uart_read32(efm_port, UARTn_IEN); | ||
173 | efm32_uart_write32(efm_port, | ||
174 | ien | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IEN); | ||
175 | efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); | ||
176 | |||
177 | efm32_uart_tx_chars(efm_port); | ||
178 | } | ||
179 | |||
180 | static void efm32_uart_stop_rx(struct uart_port *port) | ||
181 | { | ||
182 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
183 | |||
184 | efm32_uart_write32(efm_port, UARTn_CMD_RXDIS, UARTn_CMD); | ||
185 | } | ||
186 | |||
187 | static void efm32_uart_enable_ms(struct uart_port *port) | ||
188 | { | ||
189 | /* no handshake lines, no modem status interrupts */ | ||
190 | } | ||
191 | |||
192 | static void efm32_uart_break_ctl(struct uart_port *port, int ctl) | ||
193 | { | ||
194 | /* not possible without fiddling with gpios */ | ||
195 | } | ||
196 | |||
197 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | ||
198 | struct tty_struct *tty) | ||
199 | { | ||
200 | struct uart_port *port = &efm_port->port; | ||
201 | |||
202 | while (efm32_uart_read32(efm_port, UARTn_STATUS) & | ||
203 | UARTn_STATUS_RXDATAV) { | ||
204 | u32 rxdata = efm32_uart_read32(efm_port, UARTn_RXDATAX); | ||
205 | int flag = 0; | ||
206 | |||
207 | /* | ||
208 | * This is a reserved bit and I only saw it read as 0. But to be | ||
209 | * sure not to be confused too much by new devices adhere to the | ||
210 | * warning in the reference manual that reserverd bits might | ||
211 | * read as 1 in the future. | ||
212 | */ | ||
213 | rxdata &= ~SW_UARTn_RXDATAX_BERR; | ||
214 | |||
215 | port->icount.rx++; | ||
216 | |||
217 | if ((rxdata & UARTn_RXDATAX_FERR) && | ||
218 | !(rxdata & UARTn_RXDATAX_RXDATA__MASK)) { | ||
219 | rxdata |= SW_UARTn_RXDATAX_BERR; | ||
220 | port->icount.brk++; | ||
221 | if (uart_handle_break(port)) | ||
222 | continue; | ||
223 | } else if (rxdata & UARTn_RXDATAX_PERR) | ||
224 | port->icount.parity++; | ||
225 | else if (rxdata & UARTn_RXDATAX_FERR) | ||
226 | port->icount.frame++; | ||
227 | |||
228 | rxdata &= port->read_status_mask; | ||
229 | |||
230 | if (rxdata & SW_UARTn_RXDATAX_BERR) | ||
231 | flag = TTY_BREAK; | ||
232 | else if (rxdata & UARTn_RXDATAX_PERR) | ||
233 | flag = TTY_PARITY; | ||
234 | else if (rxdata & UARTn_RXDATAX_FERR) | ||
235 | flag = TTY_FRAME; | ||
236 | else if (uart_handle_sysrq_char(port, | ||
237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) | ||
238 | continue; | ||
239 | |||
240 | if (tty && (rxdata & port->ignore_status_mask) == 0) | ||
241 | tty_insert_flip_char(tty, | ||
242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | static irqreturn_t efm32_uart_rxirq(int irq, void *data) | ||
247 | { | ||
248 | struct efm32_uart_port *efm_port = data; | ||
249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); | ||
250 | int handled = IRQ_NONE; | ||
251 | struct uart_port *port = &efm_port->port; | ||
252 | struct tty_struct *tty; | ||
253 | |||
254 | spin_lock(&port->lock); | ||
255 | |||
256 | tty = tty_kref_get(port->state->port.tty); | ||
257 | |||
258 | if (irqflag & UARTn_IF_RXDATAV) { | ||
259 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); | ||
260 | efm32_uart_rx_chars(efm_port, tty); | ||
261 | |||
262 | handled = IRQ_HANDLED; | ||
263 | } | ||
264 | |||
265 | if (irqflag & UARTn_IF_RXOF) { | ||
266 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); | ||
267 | port->icount.overrun++; | ||
268 | if (tty) | ||
269 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
270 | |||
271 | handled = IRQ_HANDLED; | ||
272 | } | ||
273 | |||
274 | if (tty) { | ||
275 | tty_flip_buffer_push(tty); | ||
276 | tty_kref_put(tty); | ||
277 | } | ||
278 | |||
279 | spin_unlock(&port->lock); | ||
280 | |||
281 | return handled; | ||
282 | } | ||
283 | |||
284 | static irqreturn_t efm32_uart_txirq(int irq, void *data) | ||
285 | { | ||
286 | struct efm32_uart_port *efm_port = data; | ||
287 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); | ||
288 | |||
289 | /* TXBL doesn't need to be cleared */ | ||
290 | if (irqflag & UARTn_IF_TXC) | ||
291 | efm32_uart_write32(efm_port, UARTn_IF_TXC, UARTn_IFC); | ||
292 | |||
293 | if (irqflag & (UARTn_IF_TXC | UARTn_IF_TXBL)) { | ||
294 | efm32_uart_tx_chars(efm_port); | ||
295 | return IRQ_HANDLED; | ||
296 | } else | ||
297 | return IRQ_NONE; | ||
298 | } | ||
299 | |||
300 | static int efm32_uart_startup(struct uart_port *port) | ||
301 | { | ||
302 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
303 | u32 location = 0; | ||
304 | struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); | ||
305 | int ret; | ||
306 | |||
307 | if (pdata) | ||
308 | location = UARTn_ROUTE_LOCATION(pdata->location); | ||
309 | |||
310 | ret = clk_enable(efm_port->clk); | ||
311 | if (ret) { | ||
312 | efm_debug(efm_port, "failed to enable clk\n"); | ||
313 | goto err_clk_enable; | ||
314 | } | ||
315 | port->uartclk = clk_get_rate(efm_port->clk); | ||
316 | |||
317 | /* Enable pins at configured location */ | ||
318 | efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | ||
319 | UARTn_ROUTE); | ||
320 | |||
321 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, | ||
322 | DRIVER_NAME, efm_port); | ||
323 | if (ret) { | ||
324 | efm_debug(efm_port, "failed to register rxirq\n"); | ||
325 | goto err_request_irq_rx; | ||
326 | } | ||
327 | |||
328 | /* disable all irqs */ | ||
329 | efm32_uart_write32(efm_port, 0, UARTn_IEN); | ||
330 | |||
331 | ret = request_irq(efm_port->txirq, efm32_uart_txirq, 0, | ||
332 | DRIVER_NAME, efm_port); | ||
333 | if (ret) { | ||
334 | efm_debug(efm_port, "failed to register txirq\n"); | ||
335 | free_irq(port->irq, efm_port); | ||
336 | err_request_irq_rx: | ||
337 | |||
338 | clk_disable(efm_port->clk); | ||
339 | } else { | ||
340 | efm32_uart_write32(efm_port, | ||
341 | UARTn_IF_RXDATAV | UARTn_IF_RXOF, UARTn_IEN); | ||
342 | efm32_uart_write32(efm_port, UARTn_CMD_RXEN, UARTn_CMD); | ||
343 | } | ||
344 | |||
345 | err_clk_enable: | ||
346 | return ret; | ||
347 | } | ||
348 | |||
349 | static void efm32_uart_shutdown(struct uart_port *port) | ||
350 | { | ||
351 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
352 | |||
353 | efm32_uart_write32(efm_port, 0, UARTn_IEN); | ||
354 | free_irq(port->irq, efm_port); | ||
355 | |||
356 | clk_disable(efm_port->clk); | ||
357 | } | ||
358 | |||
359 | static void efm32_uart_set_termios(struct uart_port *port, | ||
360 | struct ktermios *new, struct ktermios *old) | ||
361 | { | ||
362 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
363 | unsigned long flags; | ||
364 | unsigned baud; | ||
365 | u32 clkdiv; | ||
366 | u32 frame = 0; | ||
367 | |||
368 | /* no modem control lines */ | ||
369 | new->c_cflag &= ~(CRTSCTS | CMSPAR); | ||
370 | |||
371 | baud = uart_get_baud_rate(port, new, old, | ||
372 | DIV_ROUND_CLOSEST(port->uartclk, 16 * 8192), | ||
373 | DIV_ROUND_CLOSEST(port->uartclk, 16)); | ||
374 | |||
375 | switch (new->c_cflag & CSIZE) { | ||
376 | case CS5: | ||
377 | frame |= UARTn_FRAME_DATABITS(5); | ||
378 | break; | ||
379 | case CS6: | ||
380 | frame |= UARTn_FRAME_DATABITS(6); | ||
381 | break; | ||
382 | case CS7: | ||
383 | frame |= UARTn_FRAME_DATABITS(7); | ||
384 | break; | ||
385 | case CS8: | ||
386 | frame |= UARTn_FRAME_DATABITS(8); | ||
387 | break; | ||
388 | } | ||
389 | |||
390 | if (new->c_cflag & CSTOPB) | ||
391 | /* the receiver only verifies the first stop bit */ | ||
392 | frame |= UARTn_FRAME_STOPBITS_TWO; | ||
393 | else | ||
394 | frame |= UARTn_FRAME_STOPBITS_ONE; | ||
395 | |||
396 | if (new->c_cflag & PARENB) { | ||
397 | if (new->c_cflag & PARODD) | ||
398 | frame |= UARTn_FRAME_PARITY_ODD; | ||
399 | else | ||
400 | frame |= UARTn_FRAME_PARITY_EVEN; | ||
401 | } else | ||
402 | frame |= UARTn_FRAME_PARITY_NONE; | ||
403 | |||
404 | /* | ||
405 | * the 6 lowest bits of CLKDIV are dc, bit 6 has value 0.25. | ||
406 | * port->uartclk <= 14e6, so 4 * port->uartclk doesn't overflow. | ||
407 | */ | ||
408 | clkdiv = (DIV_ROUND_CLOSEST(4 * port->uartclk, 16 * baud) - 4) << 6; | ||
409 | |||
410 | spin_lock_irqsave(&port->lock, flags); | ||
411 | |||
412 | efm32_uart_write32(efm_port, | ||
413 | UARTn_CMD_TXDIS | UARTn_CMD_RXDIS, UARTn_CMD); | ||
414 | |||
415 | port->read_status_mask = UARTn_RXDATAX_RXDATA__MASK; | ||
416 | if (new->c_iflag & INPCK) | ||
417 | port->read_status_mask |= | ||
418 | UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; | ||
419 | if (new->c_iflag & (BRKINT | PARMRK)) | ||
420 | port->read_status_mask |= SW_UARTn_RXDATAX_BERR; | ||
421 | |||
422 | port->ignore_status_mask = 0; | ||
423 | if (new->c_iflag & IGNPAR) | ||
424 | port->ignore_status_mask |= | ||
425 | UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; | ||
426 | if (new->c_iflag & IGNBRK) | ||
427 | port->ignore_status_mask |= SW_UARTn_RXDATAX_BERR; | ||
428 | |||
429 | uart_update_timeout(port, new->c_cflag, baud); | ||
430 | |||
431 | efm32_uart_write32(efm_port, UARTn_CTRL_TXBIL, UARTn_CTRL); | ||
432 | efm32_uart_write32(efm_port, frame, UARTn_FRAME); | ||
433 | efm32_uart_write32(efm_port, clkdiv, UARTn_CLKDIV); | ||
434 | |||
435 | efm32_uart_write32(efm_port, UARTn_CMD_TXEN | UARTn_CMD_RXEN, | ||
436 | UARTn_CMD); | ||
437 | |||
438 | spin_unlock_irqrestore(&port->lock, flags); | ||
439 | } | ||
440 | |||
441 | static const char *efm32_uart_type(struct uart_port *port) | ||
442 | { | ||
443 | return port->type == PORT_EFMUART ? "efm32-uart" : NULL; | ||
444 | } | ||
445 | |||
446 | static void efm32_uart_release_port(struct uart_port *port) | ||
447 | { | ||
448 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
449 | |||
450 | clk_unprepare(efm_port->clk); | ||
451 | clk_put(efm_port->clk); | ||
452 | iounmap(port->membase); | ||
453 | } | ||
454 | |||
455 | static int efm32_uart_request_port(struct uart_port *port) | ||
456 | { | ||
457 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
458 | int ret; | ||
459 | |||
460 | port->membase = ioremap(port->mapbase, 60); | ||
461 | if (!efm_port->port.membase) { | ||
462 | ret = -ENOMEM; | ||
463 | efm_debug(efm_port, "failed to remap\n"); | ||
464 | goto err_ioremap; | ||
465 | } | ||
466 | |||
467 | efm_port->clk = clk_get(port->dev, NULL); | ||
468 | if (IS_ERR(efm_port->clk)) { | ||
469 | ret = PTR_ERR(efm_port->clk); | ||
470 | efm_debug(efm_port, "failed to get clock\n"); | ||
471 | goto err_clk_get; | ||
472 | } | ||
473 | |||
474 | ret = clk_prepare(efm_port->clk); | ||
475 | if (ret) { | ||
476 | clk_put(efm_port->clk); | ||
477 | err_clk_get: | ||
478 | |||
479 | iounmap(port->membase); | ||
480 | err_ioremap: | ||
481 | return ret; | ||
482 | } | ||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static void efm32_uart_config_port(struct uart_port *port, int type) | ||
487 | { | ||
488 | if (type & UART_CONFIG_TYPE && | ||
489 | !efm32_uart_request_port(port)) | ||
490 | port->type = PORT_EFMUART; | ||
491 | } | ||
492 | |||
493 | static int efm32_uart_verify_port(struct uart_port *port, | ||
494 | struct serial_struct *serinfo) | ||
495 | { | ||
496 | int ret = 0; | ||
497 | |||
498 | if (serinfo->type != PORT_UNKNOWN && serinfo->type != PORT_EFMUART) | ||
499 | ret = -EINVAL; | ||
500 | |||
501 | return ret; | ||
502 | } | ||
503 | |||
504 | static struct uart_ops efm32_uart_pops = { | ||
505 | .tx_empty = efm32_uart_tx_empty, | ||
506 | .set_mctrl = efm32_uart_set_mctrl, | ||
507 | .get_mctrl = efm32_uart_get_mctrl, | ||
508 | .stop_tx = efm32_uart_stop_tx, | ||
509 | .start_tx = efm32_uart_start_tx, | ||
510 | .stop_rx = efm32_uart_stop_rx, | ||
511 | .enable_ms = efm32_uart_enable_ms, | ||
512 | .break_ctl = efm32_uart_break_ctl, | ||
513 | .startup = efm32_uart_startup, | ||
514 | .shutdown = efm32_uart_shutdown, | ||
515 | .set_termios = efm32_uart_set_termios, | ||
516 | .type = efm32_uart_type, | ||
517 | .release_port = efm32_uart_release_port, | ||
518 | .request_port = efm32_uart_request_port, | ||
519 | .config_port = efm32_uart_config_port, | ||
520 | .verify_port = efm32_uart_verify_port, | ||
521 | }; | ||
522 | |||
523 | static struct efm32_uart_port *efm32_uart_ports[5]; | ||
524 | |||
525 | #ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE | ||
526 | static void efm32_uart_console_putchar(struct uart_port *port, int ch) | ||
527 | { | ||
528 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
529 | unsigned int timeout = 0x400; | ||
530 | u32 status; | ||
531 | |||
532 | while (1) { | ||
533 | status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
534 | |||
535 | if (status & UARTn_STATUS_TXBL) | ||
536 | break; | ||
537 | if (!timeout--) | ||
538 | return; | ||
539 | } | ||
540 | efm32_uart_write32(efm_port, ch, UARTn_TXDATA); | ||
541 | } | ||
542 | |||
543 | static void efm32_uart_console_write(struct console *co, const char *s, | ||
544 | unsigned int count) | ||
545 | { | ||
546 | struct efm32_uart_port *efm_port = efm32_uart_ports[co->index]; | ||
547 | u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
548 | unsigned int timeout = 0x400; | ||
549 | |||
550 | if (!(status & UARTn_STATUS_TXENS)) | ||
551 | efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); | ||
552 | |||
553 | uart_console_write(&efm_port->port, s, count, | ||
554 | efm32_uart_console_putchar); | ||
555 | |||
556 | /* Wait for the transmitter to become empty */ | ||
557 | while (1) { | ||
558 | u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
559 | if (status & UARTn_STATUS_TXC) | ||
560 | break; | ||
561 | if (!timeout--) | ||
562 | break; | ||
563 | } | ||
564 | |||
565 | if (!(status & UARTn_STATUS_TXENS)) | ||
566 | efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); | ||
567 | } | ||
568 | |||
569 | static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port, | ||
570 | int *baud, int *parity, int *bits) | ||
571 | { | ||
572 | u32 ctrl = efm32_uart_read32(efm_port, UARTn_CTRL); | ||
573 | u32 route, clkdiv, frame; | ||
574 | |||
575 | if (ctrl & UARTn_CTRL_SYNC) | ||
576 | /* not operating in async mode */ | ||
577 | return; | ||
578 | |||
579 | route = efm32_uart_read32(efm_port, UARTn_ROUTE); | ||
580 | if (!(route & UARTn_ROUTE_TXPEN)) | ||
581 | /* tx pin not routed */ | ||
582 | return; | ||
583 | |||
584 | clkdiv = efm32_uart_read32(efm_port, UARTn_CLKDIV); | ||
585 | |||
586 | *baud = DIV_ROUND_CLOSEST(4 * efm_port->port.uartclk, | ||
587 | 16 * (4 + (clkdiv >> 6))); | ||
588 | |||
589 | frame = efm32_uart_read32(efm_port, UARTn_FRAME); | ||
590 | if (frame & UARTn_FRAME_PARITY_ODD) | ||
591 | *parity = 'o'; | ||
592 | else if (frame & UARTn_FRAME_PARITY_EVEN) | ||
593 | *parity = 'e'; | ||
594 | else | ||
595 | *parity = 'n'; | ||
596 | |||
597 | *bits = (frame & UARTn_FRAME_DATABITS__MASK) - | ||
598 | UARTn_FRAME_DATABITS(4) + 4; | ||
599 | |||
600 | efm_debug(efm_port, "get_opts: options=%d%c%d\n", | ||
601 | *baud, *parity, *bits); | ||
602 | } | ||
603 | |||
604 | static int efm32_uart_console_setup(struct console *co, char *options) | ||
605 | { | ||
606 | struct efm32_uart_port *efm_port; | ||
607 | int baud = 115200; | ||
608 | int bits = 8; | ||
609 | int parity = 'n'; | ||
610 | int flow = 'n'; | ||
611 | int ret; | ||
612 | |||
613 | if (co->index < 0 || co->index >= ARRAY_SIZE(efm32_uart_ports)) { | ||
614 | unsigned i; | ||
615 | for (i = 0; i < ARRAY_SIZE(efm32_uart_ports); ++i) { | ||
616 | if (efm32_uart_ports[i]) { | ||
617 | pr_warn("efm32-console: fall back to console index %u (from %hhi)\n", | ||
618 | i, co->index); | ||
619 | co->index = i; | ||
620 | break; | ||
621 | } | ||
622 | } | ||
623 | } | ||
624 | |||
625 | efm_port = efm32_uart_ports[co->index]; | ||
626 | if (!efm_port) { | ||
627 | pr_warn("efm32-console: No port at %d\n", co->index); | ||
628 | return -ENODEV; | ||
629 | } | ||
630 | |||
631 | ret = clk_prepare(efm_port->clk); | ||
632 | if (ret) { | ||
633 | dev_warn(efm_port->port.dev, | ||
634 | "console: clk_prepare failed: %d\n", ret); | ||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | efm_port->port.uartclk = clk_get_rate(efm_port->clk); | ||
639 | |||
640 | if (options) | ||
641 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
642 | else | ||
643 | efm32_uart_console_get_options(efm_port, | ||
644 | &baud, &parity, &bits); | ||
645 | |||
646 | return uart_set_options(&efm_port->port, co, baud, parity, bits, flow); | ||
647 | } | ||
648 | |||
649 | static struct uart_driver efm32_uart_reg; | ||
650 | |||
651 | static struct console efm32_uart_console = { | ||
652 | .name = DEV_NAME, | ||
653 | .write = efm32_uart_console_write, | ||
654 | .device = uart_console_device, | ||
655 | .setup = efm32_uart_console_setup, | ||
656 | .flags = CON_PRINTBUFFER, | ||
657 | .index = -1, | ||
658 | .data = &efm32_uart_reg, | ||
659 | }; | ||
660 | |||
661 | #else | ||
662 | #define efm32_uart_console (*(struct console *)NULL) | ||
663 | #endif /* ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE / else */ | ||
664 | |||
665 | static struct uart_driver efm32_uart_reg = { | ||
666 | .owner = THIS_MODULE, | ||
667 | .driver_name = DRIVER_NAME, | ||
668 | .dev_name = DEV_NAME, | ||
669 | .nr = ARRAY_SIZE(efm32_uart_ports), | ||
670 | .cons = &efm32_uart_console, | ||
671 | }; | ||
672 | |||
673 | static int efm32_uart_probe_dt(struct platform_device *pdev, | ||
674 | struct efm32_uart_port *efm_port) | ||
675 | { | ||
676 | struct device_node *np = pdev->dev.of_node; | ||
677 | int ret; | ||
678 | |||
679 | if (!np) | ||
680 | return 1; | ||
681 | |||
682 | ret = of_alias_get_id(np, "serial"); | ||
683 | if (ret < 0) { | ||
684 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); | ||
685 | return ret; | ||
686 | } else { | ||
687 | efm_port->port.line = ret; | ||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | } | ||
692 | |||
693 | static int __devinit efm32_uart_probe(struct platform_device *pdev) | ||
694 | { | ||
695 | struct efm32_uart_port *efm_port; | ||
696 | struct resource *res; | ||
697 | int ret; | ||
698 | |||
699 | efm_port = kzalloc(sizeof(*efm_port), GFP_KERNEL); | ||
700 | if (!efm_port) { | ||
701 | dev_dbg(&pdev->dev, "failed to allocate private data\n"); | ||
702 | return -ENOMEM; | ||
703 | } | ||
704 | |||
705 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
706 | if (!res) { | ||
707 | ret = -ENODEV; | ||
708 | dev_dbg(&pdev->dev, "failed to determine base address\n"); | ||
709 | goto err_get_base; | ||
710 | } | ||
711 | |||
712 | if (resource_size(res) < 60) { | ||
713 | ret = -EINVAL; | ||
714 | dev_dbg(&pdev->dev, "memory resource too small\n"); | ||
715 | goto err_too_small; | ||
716 | } | ||
717 | |||
718 | ret = platform_get_irq(pdev, 0); | ||
719 | if (ret <= 0) { | ||
720 | dev_dbg(&pdev->dev, "failed to get rx irq\n"); | ||
721 | goto err_get_rxirq; | ||
722 | } | ||
723 | |||
724 | efm_port->port.irq = ret; | ||
725 | |||
726 | ret = platform_get_irq(pdev, 1); | ||
727 | if (ret <= 0) | ||
728 | ret = efm_port->port.irq + 1; | ||
729 | |||
730 | efm_port->txirq = ret; | ||
731 | |||
732 | efm_port->port.dev = &pdev->dev; | ||
733 | efm_port->port.mapbase = res->start; | ||
734 | efm_port->port.type = PORT_EFMUART; | ||
735 | efm_port->port.iotype = UPIO_MEM32; | ||
736 | efm_port->port.fifosize = 2; | ||
737 | efm_port->port.ops = &efm32_uart_pops; | ||
738 | efm_port->port.flags = UPF_BOOT_AUTOCONF; | ||
739 | |||
740 | ret = efm32_uart_probe_dt(pdev, efm_port); | ||
741 | if (ret > 0) | ||
742 | /* not created by device tree */ | ||
743 | efm_port->port.line = pdev->id; | ||
744 | |||
745 | if (efm_port->port.line >= 0 && | ||
746 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) | ||
747 | efm32_uart_ports[efm_port->port.line] = efm_port; | ||
748 | |||
749 | ret = uart_add_one_port(&efm32_uart_reg, &efm_port->port); | ||
750 | if (ret) { | ||
751 | dev_dbg(&pdev->dev, "failed to add port: %d\n", ret); | ||
752 | |||
753 | if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) | ||
754 | efm32_uart_ports[pdev->id] = NULL; | ||
755 | err_get_rxirq: | ||
756 | err_too_small: | ||
757 | err_get_base: | ||
758 | kfree(efm_port); | ||
759 | } else { | ||
760 | platform_set_drvdata(pdev, efm_port); | ||
761 | dev_dbg(&pdev->dev, "\\o/\n"); | ||
762 | } | ||
763 | |||
764 | return ret; | ||
765 | } | ||
766 | |||
767 | static int __devexit efm32_uart_remove(struct platform_device *pdev) | ||
768 | { | ||
769 | struct efm32_uart_port *efm_port = platform_get_drvdata(pdev); | ||
770 | |||
771 | platform_set_drvdata(pdev, NULL); | ||
772 | |||
773 | uart_remove_one_port(&efm32_uart_reg, &efm_port->port); | ||
774 | |||
775 | if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) | ||
776 | efm32_uart_ports[pdev->id] = NULL; | ||
777 | |||
778 | kfree(efm_port); | ||
779 | |||
780 | return 0; | ||
781 | } | ||
782 | |||
783 | static struct of_device_id efm32_uart_dt_ids[] = { | ||
784 | { | ||
785 | .compatible = "efm32,uart", | ||
786 | }, { | ||
787 | /* sentinel */ | ||
788 | } | ||
789 | }; | ||
790 | MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids); | ||
791 | |||
792 | static struct platform_driver efm32_uart_driver = { | ||
793 | .probe = efm32_uart_probe, | ||
794 | .remove = __devexit_p(efm32_uart_remove), | ||
795 | |||
796 | .driver = { | ||
797 | .name = DRIVER_NAME, | ||
798 | .owner = THIS_MODULE, | ||
799 | .of_match_table = efm32_uart_dt_ids, | ||
800 | }, | ||
801 | }; | ||
802 | |||
803 | static int __init efm32_uart_init(void) | ||
804 | { | ||
805 | int ret; | ||
806 | |||
807 | ret = uart_register_driver(&efm32_uart_reg); | ||
808 | if (ret) | ||
809 | return ret; | ||
810 | |||
811 | ret = platform_driver_register(&efm32_uart_driver); | ||
812 | if (ret) | ||
813 | uart_unregister_driver(&efm32_uart_reg); | ||
814 | |||
815 | pr_info("EFM32 UART/USART driver\n"); | ||
816 | |||
817 | return ret; | ||
818 | } | ||
819 | module_init(efm32_uart_init); | ||
820 | |||
821 | static void __exit efm32_uart_exit(void) | ||
822 | { | ||
823 | platform_driver_unregister(&efm32_uart_driver); | ||
824 | uart_unregister_driver(&efm32_uart_reg); | ||
825 | } | ||
826 | |||
827 | MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); | ||
828 | MODULE_DESCRIPTION("EFM32 UART/USART driver"); | ||
829 | MODULE_LICENSE("GPL v2"); | ||
830 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||