1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> |
4 | * |
5 | * Based on msm_serial.c, which is: |
6 | * Copyright (C) 2007 Google, Inc. |
7 | * Author: Robert Love <rlove@google.com> |
8 | */ |
9 | |
10 | #include <linux/hrtimer.h> |
11 | #include <linux/delay.h> |
12 | #include <linux/io.h> |
13 | #include <linux/ioport.h> |
14 | #include <linux/irq.h> |
15 | #include <linux/init.h> |
16 | #include <linux/console.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/tty.h> |
19 | #include <linux/tty_flip.h> |
20 | #include <linux/serial_core.h> |
21 | #include <linux/serial.h> |
22 | #include <linux/slab.h> |
23 | #include <linux/clk.h> |
24 | #include <linux/of.h> |
25 | #include <linux/err.h> |
26 | |
27 | /* |
28 | * UART Register offsets |
29 | */ |
30 | |
31 | #define VT8500_URTDR 0x0000 /* Transmit data */ |
32 | #define VT8500_URRDR 0x0004 /* Receive data */ |
33 | #define VT8500_URDIV 0x0008 /* Clock/Baud rate divisor */ |
34 | #define VT8500_URLCR 0x000C /* Line control */ |
35 | #define VT8500_URICR 0x0010 /* IrDA control */ |
36 | #define VT8500_URIER 0x0014 /* Interrupt enable */ |
37 | #define VT8500_URISR 0x0018 /* Interrupt status */ |
38 | #define VT8500_URUSR 0x001c /* UART status */ |
39 | #define VT8500_URFCR 0x0020 /* FIFO control */ |
40 | #define VT8500_URFIDX 0x0024 /* FIFO index */ |
41 | #define VT8500_URBKR 0x0028 /* Break signal count */ |
42 | #define VT8500_URTOD 0x002c /* Time out divisor */ |
43 | #define VT8500_TXFIFO 0x1000 /* Transmit FIFO (16x8) */ |
44 | #define VT8500_RXFIFO 0x1020 /* Receive FIFO (16x10) */ |
45 | |
46 | /* |
47 | * Interrupt enable and status bits |
48 | */ |
49 | |
50 | #define TXDE (1 << 0) /* Tx Data empty */ |
51 | #define RXDF (1 << 1) /* Rx Data full */ |
52 | #define TXFAE (1 << 2) /* Tx FIFO almost empty */ |
53 | #define TXFE (1 << 3) /* Tx FIFO empty */ |
54 | #define RXFAF (1 << 4) /* Rx FIFO almost full */ |
55 | #define RXFF (1 << 5) /* Rx FIFO full */ |
56 | #define TXUDR (1 << 6) /* Tx underrun */ |
57 | #define RXOVER (1 << 7) /* Rx overrun */ |
58 | #define PER (1 << 8) /* Parity error */ |
59 | #define FER (1 << 9) /* Frame error */ |
60 | #define TCTS (1 << 10) /* Toggle of CTS */ |
61 | #define RXTOUT (1 << 11) /* Rx timeout */ |
62 | #define BKDONE (1 << 12) /* Break signal done */ |
63 | #define ERR (1 << 13) /* AHB error response */ |
64 | |
65 | #define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT) |
66 | #define TX_FIFO_INTS (TXFAE | TXFE | TXUDR) |
67 | |
68 | /* |
69 | * Line control bits |
70 | */ |
71 | |
72 | #define VT8500_TXEN (1 << 0) /* Enable transmit logic */ |
73 | #define VT8500_RXEN (1 << 1) /* Enable receive logic */ |
74 | #define VT8500_CS8 (1 << 2) /* 8-bit data length (vs. 7-bit) */ |
75 | #define VT8500_CSTOPB (1 << 3) /* 2 stop bits (vs. 1) */ |
76 | #define VT8500_PARENB (1 << 4) /* Enable parity */ |
77 | #define VT8500_PARODD (1 << 5) /* Odd parity (vs. even) */ |
78 | #define VT8500_RTS (1 << 6) /* Ready to send */ |
79 | #define VT8500_LOOPBK (1 << 7) /* Enable internal loopback */ |
80 | #define VT8500_DMA (1 << 8) /* Enable DMA mode (needs FIFO) */ |
81 | #define VT8500_BREAK (1 << 9) /* Initiate break signal */ |
82 | #define VT8500_PSLVERR (1 << 10) /* APB error upon empty RX FIFO read */ |
83 | #define VT8500_SWRTSCTS (1 << 11) /* Software-controlled RTS/CTS */ |
84 | |
85 | /* |
86 | * Capability flags (driver-internal) |
87 | */ |
88 | |
89 | #define VT8500_HAS_SWRTSCTS_SWITCH (1 << 1) |
90 | |
91 | #define VT8500_RECOMMENDED_CLK 12000000 |
92 | #define VT8500_OVERSAMPLING_DIVISOR 13 |
93 | #define VT8500_MAX_PORTS 6 |
94 | |
95 | struct vt8500_port { |
96 | struct uart_port uart; |
97 | char name[16]; |
98 | struct clk *clk; |
99 | unsigned int clk_predivisor; |
100 | unsigned int ier; |
101 | unsigned int vt8500_uart_flags; |
102 | }; |
103 | |
104 | /* |
105 | * we use this variable to keep track of which ports |
106 | * have been allocated as we can't use pdev->id in |
107 | * devicetree |
108 | */ |
109 | static DECLARE_BITMAP(vt8500_ports_in_use, VT8500_MAX_PORTS); |
110 | |
111 | static inline void vt8500_write(struct uart_port *port, unsigned int val, |
112 | unsigned int off) |
113 | { |
114 | writel(val, addr: port->membase + off); |
115 | } |
116 | |
117 | static inline unsigned int vt8500_read(struct uart_port *port, unsigned int off) |
118 | { |
119 | return readl(addr: port->membase + off); |
120 | } |
121 | |
122 | static void vt8500_stop_tx(struct uart_port *port) |
123 | { |
124 | struct vt8500_port *vt8500_port = container_of(port, |
125 | struct vt8500_port, |
126 | uart); |
127 | |
128 | vt8500_port->ier &= ~TX_FIFO_INTS; |
129 | vt8500_write(port, val: vt8500_port->ier, VT8500_URIER); |
130 | } |
131 | |
132 | static void vt8500_stop_rx(struct uart_port *port) |
133 | { |
134 | struct vt8500_port *vt8500_port = container_of(port, |
135 | struct vt8500_port, |
136 | uart); |
137 | |
138 | vt8500_port->ier &= ~RX_FIFO_INTS; |
139 | vt8500_write(port, val: vt8500_port->ier, VT8500_URIER); |
140 | } |
141 | |
142 | static void vt8500_enable_ms(struct uart_port *port) |
143 | { |
144 | struct vt8500_port *vt8500_port = container_of(port, |
145 | struct vt8500_port, |
146 | uart); |
147 | |
148 | vt8500_port->ier |= TCTS; |
149 | vt8500_write(port, val: vt8500_port->ier, VT8500_URIER); |
150 | } |
151 | |
152 | static void handle_rx(struct uart_port *port) |
153 | { |
154 | struct tty_port *tport = &port->state->port; |
155 | |
156 | /* |
157 | * Handle overrun |
158 | */ |
159 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { |
160 | port->icount.overrun++; |
161 | tty_insert_flip_char(port: tport, ch: 0, TTY_OVERRUN); |
162 | } |
163 | |
164 | /* and now the main RX loop */ |
165 | while (vt8500_read(port, VT8500_URFIDX) & 0x1f00) { |
166 | unsigned int c; |
167 | char flag = TTY_NORMAL; |
168 | |
169 | c = readw(addr: port->membase + VT8500_RXFIFO) & 0x3ff; |
170 | |
171 | /* Mask conditions we're ignoring. */ |
172 | c &= ~port->read_status_mask; |
173 | |
174 | if (c & FER) { |
175 | port->icount.frame++; |
176 | flag = TTY_FRAME; |
177 | } else if (c & PER) { |
178 | port->icount.parity++; |
179 | flag = TTY_PARITY; |
180 | } |
181 | port->icount.rx++; |
182 | |
183 | if (!uart_handle_sysrq_char(port, ch: c)) |
184 | tty_insert_flip_char(port: tport, ch: c, flag); |
185 | } |
186 | |
187 | tty_flip_buffer_push(port: tport); |
188 | } |
189 | |
190 | static unsigned int vt8500_tx_empty(struct uart_port *port) |
191 | { |
192 | unsigned int idx = vt8500_read(port, VT8500_URFIDX) & 0x1f; |
193 | |
194 | return idx < 16 ? TIOCSER_TEMT : 0; |
195 | } |
196 | |
197 | static void handle_tx(struct uart_port *port) |
198 | { |
199 | u8 ch; |
200 | |
201 | uart_port_tx(port, ch, |
202 | vt8500_tx_empty(port), |
203 | writeb(ch, port->membase + VT8500_TXFIFO)); |
204 | } |
205 | |
206 | static void vt8500_start_tx(struct uart_port *port) |
207 | { |
208 | struct vt8500_port *vt8500_port = container_of(port, |
209 | struct vt8500_port, |
210 | uart); |
211 | |
212 | vt8500_port->ier &= ~TX_FIFO_INTS; |
213 | vt8500_write(port, val: vt8500_port->ier, VT8500_URIER); |
214 | handle_tx(port); |
215 | vt8500_port->ier |= TX_FIFO_INTS; |
216 | vt8500_write(port, val: vt8500_port->ier, VT8500_URIER); |
217 | } |
218 | |
219 | static void handle_delta_cts(struct uart_port *port) |
220 | { |
221 | port->icount.cts++; |
222 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
223 | } |
224 | |
225 | static irqreturn_t vt8500_irq(int irq, void *dev_id) |
226 | { |
227 | struct uart_port *port = dev_id; |
228 | unsigned long isr; |
229 | |
230 | uart_port_lock(up: port); |
231 | isr = vt8500_read(port, VT8500_URISR); |
232 | |
233 | /* Acknowledge active status bits */ |
234 | vt8500_write(port, val: isr, VT8500_URISR); |
235 | |
236 | if (isr & RX_FIFO_INTS) |
237 | handle_rx(port); |
238 | if (isr & TX_FIFO_INTS) |
239 | handle_tx(port); |
240 | if (isr & TCTS) |
241 | handle_delta_cts(port); |
242 | |
243 | uart_port_unlock(up: port); |
244 | |
245 | return IRQ_HANDLED; |
246 | } |
247 | |
248 | static unsigned int vt8500_get_mctrl(struct uart_port *port) |
249 | { |
250 | unsigned int usr; |
251 | |
252 | usr = vt8500_read(port, VT8500_URUSR); |
253 | if (usr & (1 << 4)) |
254 | return TIOCM_CTS; |
255 | else |
256 | return 0; |
257 | } |
258 | |
259 | static void vt8500_set_mctrl(struct uart_port *port, unsigned int mctrl) |
260 | { |
261 | unsigned int lcr = vt8500_read(port, VT8500_URLCR); |
262 | |
263 | if (mctrl & TIOCM_RTS) |
264 | lcr |= VT8500_RTS; |
265 | else |
266 | lcr &= ~VT8500_RTS; |
267 | |
268 | vt8500_write(port, val: lcr, VT8500_URLCR); |
269 | } |
270 | |
271 | static void vt8500_break_ctl(struct uart_port *port, int break_ctl) |
272 | { |
273 | if (break_ctl) |
274 | vt8500_write(port, |
275 | val: vt8500_read(port, VT8500_URLCR) | VT8500_BREAK, |
276 | VT8500_URLCR); |
277 | } |
278 | |
279 | static int vt8500_set_baud_rate(struct uart_port *port, unsigned int baud) |
280 | { |
281 | struct vt8500_port *vt8500_port = |
282 | container_of(port, struct vt8500_port, uart); |
283 | unsigned long div; |
284 | unsigned int loops = 1000; |
285 | |
286 | div = ((vt8500_port->clk_predivisor - 1) & 0xf) << 16; |
287 | div |= (uart_get_divisor(port, baud) - 1) & 0x3ff; |
288 | |
289 | /* Effective baud rate */ |
290 | baud = port->uartclk / 16 / ((div & 0x3ff) + 1); |
291 | |
292 | while ((vt8500_read(port, VT8500_URUSR) & (1 << 5)) && --loops) |
293 | cpu_relax(); |
294 | |
295 | vt8500_write(port, val: div, VT8500_URDIV); |
296 | |
297 | /* Break signal timing depends on baud rate, update accordingly */ |
298 | vt8500_write(port, mult_frac(baud, 4096, 1000000), VT8500_URBKR); |
299 | |
300 | return baud; |
301 | } |
302 | |
303 | static int vt8500_startup(struct uart_port *port) |
304 | { |
305 | struct vt8500_port *vt8500_port = |
306 | container_of(port, struct vt8500_port, uart); |
307 | int ret; |
308 | |
309 | snprintf(buf: vt8500_port->name, size: sizeof(vt8500_port->name), |
310 | fmt: "vt8500_serial%d" , port->line); |
311 | |
312 | ret = request_irq(irq: port->irq, handler: vt8500_irq, IRQF_TRIGGER_HIGH, |
313 | name: vt8500_port->name, dev: port); |
314 | if (unlikely(ret)) |
315 | return ret; |
316 | |
317 | vt8500_write(port, val: 0x03, VT8500_URLCR); /* enable TX & RX */ |
318 | |
319 | return 0; |
320 | } |
321 | |
322 | static void vt8500_shutdown(struct uart_port *port) |
323 | { |
324 | struct vt8500_port *vt8500_port = |
325 | container_of(port, struct vt8500_port, uart); |
326 | |
327 | vt8500_port->ier = 0; |
328 | |
329 | /* disable interrupts and FIFOs */ |
330 | vt8500_write(port: &vt8500_port->uart, val: 0, VT8500_URIER); |
331 | vt8500_write(port: &vt8500_port->uart, val: 0x880, VT8500_URFCR); |
332 | free_irq(port->irq, port); |
333 | } |
334 | |
335 | static void vt8500_set_termios(struct uart_port *port, |
336 | struct ktermios *termios, |
337 | const struct ktermios *old) |
338 | { |
339 | struct vt8500_port *vt8500_port = |
340 | container_of(port, struct vt8500_port, uart); |
341 | unsigned long flags; |
342 | unsigned int baud, lcr; |
343 | unsigned int loops = 1000; |
344 | |
345 | uart_port_lock_irqsave(up: port, flags: &flags); |
346 | |
347 | /* calculate and set baud rate */ |
348 | baud = uart_get_baud_rate(port, termios, old, min: 900, max: 921600); |
349 | baud = vt8500_set_baud_rate(port, baud); |
350 | if (tty_termios_baud_rate(termios)) |
351 | tty_termios_encode_baud_rate(termios, ibaud: baud, obaud: baud); |
352 | |
353 | /* calculate parity */ |
354 | lcr = vt8500_read(port: &vt8500_port->uart, VT8500_URLCR); |
355 | lcr &= ~(VT8500_PARENB | VT8500_PARODD); |
356 | if (termios->c_cflag & PARENB) { |
357 | lcr |= VT8500_PARENB; |
358 | termios->c_cflag &= ~CMSPAR; |
359 | if (termios->c_cflag & PARODD) |
360 | lcr |= VT8500_PARODD; |
361 | } |
362 | |
363 | /* calculate bits per char */ |
364 | lcr &= ~VT8500_CS8; |
365 | switch (termios->c_cflag & CSIZE) { |
366 | case CS7: |
367 | break; |
368 | case CS8: |
369 | default: |
370 | lcr |= VT8500_CS8; |
371 | termios->c_cflag &= ~CSIZE; |
372 | termios->c_cflag |= CS8; |
373 | break; |
374 | } |
375 | |
376 | /* calculate stop bits */ |
377 | lcr &= ~VT8500_CSTOPB; |
378 | if (termios->c_cflag & CSTOPB) |
379 | lcr |= VT8500_CSTOPB; |
380 | |
381 | lcr &= ~VT8500_SWRTSCTS; |
382 | if (vt8500_port->vt8500_uart_flags & VT8500_HAS_SWRTSCTS_SWITCH) |
383 | lcr |= VT8500_SWRTSCTS; |
384 | |
385 | /* set parity, bits per char, and stop bit */ |
386 | vt8500_write(port: &vt8500_port->uart, val: lcr, VT8500_URLCR); |
387 | |
388 | /* Configure status bits to ignore based on termio flags. */ |
389 | port->read_status_mask = 0; |
390 | if (termios->c_iflag & IGNPAR) |
391 | port->read_status_mask = FER | PER; |
392 | |
393 | uart_update_timeout(port, cflag: termios->c_cflag, baud); |
394 | |
395 | /* Reset FIFOs */ |
396 | vt8500_write(port: &vt8500_port->uart, val: 0x88c, VT8500_URFCR); |
397 | while ((vt8500_read(port: &vt8500_port->uart, VT8500_URFCR) & 0xc) |
398 | && --loops) |
399 | cpu_relax(); |
400 | |
401 | /* Every possible FIFO-related interrupt */ |
402 | vt8500_port->ier = RX_FIFO_INTS | TX_FIFO_INTS; |
403 | |
404 | /* |
405 | * CTS flow control |
406 | */ |
407 | if (UART_ENABLE_MS(&vt8500_port->uart, termios->c_cflag)) |
408 | vt8500_port->ier |= TCTS; |
409 | |
410 | vt8500_write(port: &vt8500_port->uart, val: 0x881, VT8500_URFCR); |
411 | vt8500_write(port: &vt8500_port->uart, val: vt8500_port->ier, VT8500_URIER); |
412 | |
413 | uart_port_unlock_irqrestore(up: port, flags); |
414 | } |
415 | |
416 | static const char *vt8500_type(struct uart_port *port) |
417 | { |
418 | struct vt8500_port *vt8500_port = |
419 | container_of(port, struct vt8500_port, uart); |
420 | return vt8500_port->name; |
421 | } |
422 | |
423 | static void vt8500_release_port(struct uart_port *port) |
424 | { |
425 | } |
426 | |
427 | static int vt8500_request_port(struct uart_port *port) |
428 | { |
429 | return 0; |
430 | } |
431 | |
432 | static void vt8500_config_port(struct uart_port *port, int flags) |
433 | { |
434 | port->type = PORT_VT8500; |
435 | } |
436 | |
437 | static int vt8500_verify_port(struct uart_port *port, |
438 | struct serial_struct *ser) |
439 | { |
440 | if (unlikely(ser->type != PORT_UNKNOWN && ser->type != PORT_VT8500)) |
441 | return -EINVAL; |
442 | if (unlikely(port->irq != ser->irq)) |
443 | return -EINVAL; |
444 | return 0; |
445 | } |
446 | |
447 | static struct vt8500_port *vt8500_uart_ports[VT8500_MAX_PORTS]; |
448 | static struct uart_driver vt8500_uart_driver; |
449 | |
450 | #ifdef CONFIG_SERIAL_VT8500_CONSOLE |
451 | |
452 | static void wait_for_xmitr(struct uart_port *port) |
453 | { |
454 | unsigned int status, tmout = 10000; |
455 | |
456 | /* Wait up to 10ms for the character(s) to be sent. */ |
457 | do { |
458 | status = vt8500_read(port, VT8500_URFIDX); |
459 | |
460 | if (--tmout == 0) |
461 | break; |
462 | udelay(1); |
463 | } while (status & 0x10); |
464 | } |
465 | |
466 | static void vt8500_console_putchar(struct uart_port *port, unsigned char c) |
467 | { |
468 | wait_for_xmitr(port); |
469 | writeb(val: c, addr: port->membase + VT8500_TXFIFO); |
470 | } |
471 | |
472 | static void vt8500_console_write(struct console *co, const char *s, |
473 | unsigned int count) |
474 | { |
475 | struct vt8500_port *vt8500_port = vt8500_uart_ports[co->index]; |
476 | unsigned long ier; |
477 | |
478 | BUG_ON(co->index < 0 || co->index >= vt8500_uart_driver.nr); |
479 | |
480 | ier = vt8500_read(port: &vt8500_port->uart, VT8500_URIER); |
481 | vt8500_write(port: &vt8500_port->uart, VT8500_URIER, off: 0); |
482 | |
483 | uart_console_write(port: &vt8500_port->uart, s, count, |
484 | putchar: vt8500_console_putchar); |
485 | |
486 | /* |
487 | * Finally, wait for transmitter to become empty |
488 | * and switch back to FIFO |
489 | */ |
490 | wait_for_xmitr(port: &vt8500_port->uart); |
491 | vt8500_write(port: &vt8500_port->uart, VT8500_URIER, off: ier); |
492 | } |
493 | |
494 | static int __init vt8500_console_setup(struct console *co, char *options) |
495 | { |
496 | struct vt8500_port *vt8500_port; |
497 | int baud = 9600; |
498 | int bits = 8; |
499 | int parity = 'n'; |
500 | int flow = 'n'; |
501 | |
502 | if (unlikely(co->index >= vt8500_uart_driver.nr || co->index < 0)) |
503 | return -ENXIO; |
504 | |
505 | vt8500_port = vt8500_uart_ports[co->index]; |
506 | |
507 | if (!vt8500_port) |
508 | return -ENODEV; |
509 | |
510 | if (options) |
511 | uart_parse_options(options, baud: &baud, parity: &parity, bits: &bits, flow: &flow); |
512 | |
513 | return uart_set_options(port: &vt8500_port->uart, |
514 | co, baud, parity, bits, flow); |
515 | } |
516 | |
517 | static struct console vt8500_console = { |
518 | .name = "ttyWMT" , |
519 | .write = vt8500_console_write, |
520 | .device = uart_console_device, |
521 | .setup = vt8500_console_setup, |
522 | .flags = CON_PRINTBUFFER, |
523 | .index = -1, |
524 | .data = &vt8500_uart_driver, |
525 | }; |
526 | |
527 | #define VT8500_CONSOLE (&vt8500_console) |
528 | |
529 | #else |
530 | #define VT8500_CONSOLE NULL |
531 | #endif |
532 | |
533 | #ifdef CONFIG_CONSOLE_POLL |
534 | static int vt8500_get_poll_char(struct uart_port *port) |
535 | { |
536 | unsigned int status = vt8500_read(port, VT8500_URFIDX); |
537 | |
538 | if (!(status & 0x1f00)) |
539 | return NO_POLL_CHAR; |
540 | |
541 | return vt8500_read(port, VT8500_RXFIFO) & 0xff; |
542 | } |
543 | |
544 | static void vt8500_put_poll_char(struct uart_port *port, unsigned char c) |
545 | { |
546 | unsigned int status, tmout = 10000; |
547 | |
548 | do { |
549 | status = vt8500_read(port, VT8500_URFIDX); |
550 | |
551 | if (--tmout == 0) |
552 | break; |
553 | udelay(1); |
554 | } while (status & 0x10); |
555 | |
556 | vt8500_write(port, val: c, VT8500_TXFIFO); |
557 | } |
558 | #endif |
559 | |
560 | static const struct uart_ops vt8500_uart_pops = { |
561 | .tx_empty = vt8500_tx_empty, |
562 | .set_mctrl = vt8500_set_mctrl, |
563 | .get_mctrl = vt8500_get_mctrl, |
564 | .stop_tx = vt8500_stop_tx, |
565 | .start_tx = vt8500_start_tx, |
566 | .stop_rx = vt8500_stop_rx, |
567 | .enable_ms = vt8500_enable_ms, |
568 | .break_ctl = vt8500_break_ctl, |
569 | .startup = vt8500_startup, |
570 | .shutdown = vt8500_shutdown, |
571 | .set_termios = vt8500_set_termios, |
572 | .type = vt8500_type, |
573 | .release_port = vt8500_release_port, |
574 | .request_port = vt8500_request_port, |
575 | .config_port = vt8500_config_port, |
576 | .verify_port = vt8500_verify_port, |
577 | #ifdef CONFIG_CONSOLE_POLL |
578 | .poll_get_char = vt8500_get_poll_char, |
579 | .poll_put_char = vt8500_put_poll_char, |
580 | #endif |
581 | }; |
582 | |
583 | static struct uart_driver vt8500_uart_driver = { |
584 | .owner = THIS_MODULE, |
585 | .driver_name = "vt8500_serial" , |
586 | .dev_name = "ttyWMT" , |
587 | .nr = 6, |
588 | .cons = VT8500_CONSOLE, |
589 | }; |
590 | |
591 | static unsigned int vt8500_flags; /* none required so far */ |
592 | static unsigned int wm8880_flags = VT8500_HAS_SWRTSCTS_SWITCH; |
593 | |
594 | static const struct of_device_id wmt_dt_ids[] = { |
595 | { .compatible = "via,vt8500-uart" , .data = &vt8500_flags}, |
596 | { .compatible = "wm,wm8880-uart" , .data = &wm8880_flags}, |
597 | {} |
598 | }; |
599 | |
600 | static int vt8500_serial_probe(struct platform_device *pdev) |
601 | { |
602 | struct vt8500_port *vt8500_port; |
603 | struct resource *mmres; |
604 | struct device_node *np = pdev->dev.of_node; |
605 | const unsigned int *flags; |
606 | int ret; |
607 | int port; |
608 | int irq; |
609 | |
610 | flags = of_device_get_match_data(dev: &pdev->dev); |
611 | if (!flags) |
612 | return -EINVAL; |
613 | |
614 | irq = platform_get_irq(pdev, 0); |
615 | if (irq < 0) |
616 | return irq; |
617 | |
618 | if (np) { |
619 | port = of_alias_get_id(np, stem: "serial" ); |
620 | if (port >= VT8500_MAX_PORTS) |
621 | port = -1; |
622 | } else { |
623 | port = -1; |
624 | } |
625 | |
626 | if (port < 0) { |
627 | /* calculate the port id */ |
628 | port = find_first_zero_bit(addr: vt8500_ports_in_use, |
629 | VT8500_MAX_PORTS); |
630 | } |
631 | |
632 | if (port >= VT8500_MAX_PORTS) |
633 | return -ENODEV; |
634 | |
635 | /* reserve the port id */ |
636 | if (test_and_set_bit(nr: port, addr: vt8500_ports_in_use)) { |
637 | /* port already in use - shouldn't really happen */ |
638 | return -EBUSY; |
639 | } |
640 | |
641 | vt8500_port = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct vt8500_port), |
642 | GFP_KERNEL); |
643 | if (!vt8500_port) |
644 | return -ENOMEM; |
645 | |
646 | vt8500_port->uart.membase = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &mmres); |
647 | if (IS_ERR(ptr: vt8500_port->uart.membase)) |
648 | return PTR_ERR(ptr: vt8500_port->uart.membase); |
649 | |
650 | vt8500_port->clk = of_clk_get(np: pdev->dev.of_node, index: 0); |
651 | if (IS_ERR(ptr: vt8500_port->clk)) { |
652 | dev_err(&pdev->dev, "failed to get clock\n" ); |
653 | return -EINVAL; |
654 | } |
655 | |
656 | ret = clk_prepare_enable(clk: vt8500_port->clk); |
657 | if (ret) { |
658 | dev_err(&pdev->dev, "failed to enable clock\n" ); |
659 | return ret; |
660 | } |
661 | |
662 | vt8500_port->vt8500_uart_flags = *flags; |
663 | vt8500_port->clk_predivisor = DIV_ROUND_CLOSEST( |
664 | clk_get_rate(vt8500_port->clk), |
665 | VT8500_RECOMMENDED_CLK |
666 | ); |
667 | vt8500_port->uart.type = PORT_VT8500; |
668 | vt8500_port->uart.iotype = UPIO_MEM; |
669 | vt8500_port->uart.mapbase = mmres->start; |
670 | vt8500_port->uart.irq = irq; |
671 | vt8500_port->uart.fifosize = 16; |
672 | vt8500_port->uart.ops = &vt8500_uart_pops; |
673 | vt8500_port->uart.line = port; |
674 | vt8500_port->uart.dev = &pdev->dev; |
675 | vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; |
676 | vt8500_port->uart.has_sysrq = IS_ENABLED(CONFIG_SERIAL_VT8500_CONSOLE); |
677 | |
678 | /* Serial core uses the magic "16" everywhere - adjust for it */ |
679 | vt8500_port->uart.uartclk = 16 * clk_get_rate(clk: vt8500_port->clk) / |
680 | vt8500_port->clk_predivisor / |
681 | VT8500_OVERSAMPLING_DIVISOR; |
682 | |
683 | snprintf(buf: vt8500_port->name, size: sizeof(vt8500_port->name), |
684 | fmt: "VT8500 UART%d" , pdev->id); |
685 | |
686 | vt8500_uart_ports[port] = vt8500_port; |
687 | |
688 | uart_add_one_port(reg: &vt8500_uart_driver, port: &vt8500_port->uart); |
689 | |
690 | platform_set_drvdata(pdev, data: vt8500_port); |
691 | |
692 | return 0; |
693 | } |
694 | |
695 | static struct platform_driver vt8500_platform_driver = { |
696 | .probe = vt8500_serial_probe, |
697 | .driver = { |
698 | .name = "vt8500_serial" , |
699 | .of_match_table = wmt_dt_ids, |
700 | .suppress_bind_attrs = true, |
701 | }, |
702 | }; |
703 | |
704 | static int __init vt8500_serial_init(void) |
705 | { |
706 | int ret; |
707 | |
708 | ret = uart_register_driver(uart: &vt8500_uart_driver); |
709 | if (unlikely(ret)) |
710 | return ret; |
711 | |
712 | ret = platform_driver_register(&vt8500_platform_driver); |
713 | |
714 | if (unlikely(ret)) |
715 | uart_unregister_driver(uart: &vt8500_uart_driver); |
716 | |
717 | return ret; |
718 | } |
719 | device_initcall(vt8500_serial_init); |
720 | |