]> Git Repo - linux.git/blob - drivers/tty/serial/meson_uart.c
Linux 6.14-rc3
[linux.git] / drivers / tty / serial / meson_uart.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  Based on meson_uart.c, by AMLOGIC, INC.
4  *
5  * Copyright (C) 2014 Carlo Caione <[email protected]>
6  */
7
8 #include <linux/clk.h>
9 #include <linux/console.h>
10 #include <linux/delay.h>
11 #include <linux/init.h>
12 #include <linux/io.h>
13 #include <linux/iopoll.h>
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/of.h>
17 #include <linux/platform_device.h>
18 #include <linux/serial.h>
19 #include <linux/serial_core.h>
20 #include <linux/tty.h>
21 #include <linux/tty_flip.h>
22
23 /* Register offsets */
24 #define AML_UART_WFIFO                  0x00
25 #define AML_UART_RFIFO                  0x04
26 #define AML_UART_CONTROL                0x08
27 #define AML_UART_STATUS                 0x0c
28 #define AML_UART_MISC                   0x10
29 #define AML_UART_REG5                   0x14
30
31 /* AML_UART_CONTROL bits */
32 #define AML_UART_TX_EN                  BIT(12)
33 #define AML_UART_RX_EN                  BIT(13)
34 #define AML_UART_TWO_WIRE_EN            BIT(15)
35 #define AML_UART_STOP_BIT_LEN_MASK      (0x03 << 16)
36 #define AML_UART_STOP_BIT_1SB           (0x00 << 16)
37 #define AML_UART_STOP_BIT_2SB           (0x01 << 16)
38 #define AML_UART_PARITY_TYPE            BIT(18)
39 #define AML_UART_PARITY_EN              BIT(19)
40 #define AML_UART_TX_RST                 BIT(22)
41 #define AML_UART_RX_RST                 BIT(23)
42 #define AML_UART_CLEAR_ERR              BIT(24)
43 #define AML_UART_RX_INT_EN              BIT(27)
44 #define AML_UART_TX_INT_EN              BIT(28)
45 #define AML_UART_DATA_LEN_MASK          (0x03 << 20)
46 #define AML_UART_DATA_LEN_8BIT          (0x00 << 20)
47 #define AML_UART_DATA_LEN_7BIT          (0x01 << 20)
48 #define AML_UART_DATA_LEN_6BIT          (0x02 << 20)
49 #define AML_UART_DATA_LEN_5BIT          (0x03 << 20)
50
51 /* AML_UART_STATUS bits */
52 #define AML_UART_PARITY_ERR             BIT(16)
53 #define AML_UART_FRAME_ERR              BIT(17)
54 #define AML_UART_TX_FIFO_WERR           BIT(18)
55 #define AML_UART_RX_EMPTY               BIT(20)
56 #define AML_UART_TX_FULL                BIT(21)
57 #define AML_UART_TX_EMPTY               BIT(22)
58 #define AML_UART_XMIT_BUSY              BIT(25)
59 #define AML_UART_ERR                    (AML_UART_PARITY_ERR | \
60                                          AML_UART_FRAME_ERR  | \
61                                          AML_UART_TX_FIFO_WERR)
62
63 /* AML_UART_MISC bits */
64 #define AML_UART_XMIT_IRQ(c)            (((c) & 0xff) << 8)
65 #define AML_UART_RECV_IRQ(c)            ((c) & 0xff)
66
67 /* AML_UART_REG5 bits */
68 #define AML_UART_BAUD_MASK              0x7fffff
69 #define AML_UART_BAUD_USE               BIT(23)
70 #define AML_UART_BAUD_XTAL              BIT(24)
71 #define AML_UART_BAUD_XTAL_DIV2         BIT(27)
72
73 #define AML_UART_PORT_NUM               12
74 #define AML_UART_PORT_OFFSET            6
75
76 #define AML_UART_POLL_USEC              5
77 #define AML_UART_TIMEOUT_USEC           10000
78
79 static struct uart_driver meson_uart_driver_ttyAML;
80 static struct uart_driver meson_uart_driver_ttyS;
81
82 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
83
84 struct meson_uart_data {
85         struct uart_driver *uart_driver;
86         bool has_xtal_div2;
87 };
88
89 static void meson_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
90 {
91 }
92
93 static unsigned int meson_uart_get_mctrl(struct uart_port *port)
94 {
95         return TIOCM_CTS;
96 }
97
98 static unsigned int meson_uart_tx_empty(struct uart_port *port)
99 {
100         u32 val;
101
102         val = readl(port->membase + AML_UART_STATUS);
103         val &= (AML_UART_TX_EMPTY | AML_UART_XMIT_BUSY);
104         return (val == AML_UART_TX_EMPTY) ? TIOCSER_TEMT : 0;
105 }
106
107 static void meson_uart_stop_tx(struct uart_port *port)
108 {
109         u32 val;
110
111         val = readl(port->membase + AML_UART_CONTROL);
112         val &= ~AML_UART_TX_INT_EN;
113         writel(val, port->membase + AML_UART_CONTROL);
114 }
115
116 static void meson_uart_stop_rx(struct uart_port *port)
117 {
118         u32 val;
119
120         val = readl(port->membase + AML_UART_CONTROL);
121         val &= ~AML_UART_RX_EN;
122         writel(val, port->membase + AML_UART_CONTROL);
123 }
124
125 static void meson_uart_shutdown(struct uart_port *port)
126 {
127         unsigned long flags;
128         u32 val;
129
130         free_irq(port->irq, port);
131
132         uart_port_lock_irqsave(port, &flags);
133
134         val = readl(port->membase + AML_UART_CONTROL);
135         val &= ~AML_UART_RX_EN;
136         val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
137         writel(val, port->membase + AML_UART_CONTROL);
138
139         uart_port_unlock_irqrestore(port, flags);
140 }
141
142 static void meson_uart_start_tx(struct uart_port *port)
143 {
144         struct tty_port *tport = &port->state->port;
145         unsigned char ch;
146         u32 val;
147
148         if (uart_tx_stopped(port)) {
149                 meson_uart_stop_tx(port);
150                 return;
151         }
152
153         while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) {
154                 if (port->x_char) {
155                         writel(port->x_char, port->membase + AML_UART_WFIFO);
156                         port->icount.tx++;
157                         port->x_char = 0;
158                         continue;
159                 }
160
161                 if (!uart_fifo_get(port, &ch))
162                         break;
163
164                 writel(ch, port->membase + AML_UART_WFIFO);
165         }
166
167         if (!kfifo_is_empty(&tport->xmit_fifo)) {
168                 val = readl(port->membase + AML_UART_CONTROL);
169                 val |= AML_UART_TX_INT_EN;
170                 writel(val, port->membase + AML_UART_CONTROL);
171         }
172
173         if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
174                 uart_write_wakeup(port);
175 }
176
177 static void meson_receive_chars(struct uart_port *port)
178 {
179         struct tty_port *tport = &port->state->port;
180         char flag;
181         u32 ostatus, status, ch, mode;
182
183         do {
184                 flag = TTY_NORMAL;
185                 port->icount.rx++;
186                 ostatus = status = readl(port->membase + AML_UART_STATUS);
187
188                 if (status & AML_UART_ERR) {
189                         if (status & AML_UART_TX_FIFO_WERR)
190                                 port->icount.overrun++;
191                         else if (status & AML_UART_FRAME_ERR)
192                                 port->icount.frame++;
193                         else if (status & AML_UART_PARITY_ERR)
194                                 port->icount.frame++;
195
196                         mode = readl(port->membase + AML_UART_CONTROL);
197                         mode |= AML_UART_CLEAR_ERR;
198                         writel(mode, port->membase + AML_UART_CONTROL);
199
200                         /* It doesn't clear to 0 automatically */
201                         mode &= ~AML_UART_CLEAR_ERR;
202                         writel(mode, port->membase + AML_UART_CONTROL);
203
204                         status &= port->read_status_mask;
205                         if (status & AML_UART_FRAME_ERR)
206                                 flag = TTY_FRAME;
207                         else if (status & AML_UART_PARITY_ERR)
208                                 flag = TTY_PARITY;
209                 }
210
211                 ch = readl(port->membase + AML_UART_RFIFO);
212                 ch &= 0xff;
213
214                 if ((ostatus & AML_UART_FRAME_ERR) && (ch == 0)) {
215                         port->icount.brk++;
216                         flag = TTY_BREAK;
217                         if (uart_handle_break(port))
218                                 continue;
219                 }
220
221                 if (uart_prepare_sysrq_char(port, ch))
222                         continue;
223
224                 if ((status & port->ignore_status_mask) == 0)
225                         tty_insert_flip_char(tport, ch, flag);
226
227                 if (status & AML_UART_TX_FIFO_WERR)
228                         tty_insert_flip_char(tport, 0, TTY_OVERRUN);
229
230         } while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY));
231
232         tty_flip_buffer_push(tport);
233 }
234
235 static irqreturn_t meson_uart_interrupt(int irq, void *dev_id)
236 {
237         struct uart_port *port = (struct uart_port *)dev_id;
238
239         uart_port_lock(port);
240
241         if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY))
242                 meson_receive_chars(port);
243
244         if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) {
245                 if (readl(port->membase + AML_UART_CONTROL) & AML_UART_TX_INT_EN)
246                         meson_uart_start_tx(port);
247         }
248
249         uart_unlock_and_check_sysrq(port);
250
251         return IRQ_HANDLED;
252 }
253
254 static const char *meson_uart_type(struct uart_port *port)
255 {
256         return (port->type == PORT_MESON) ? "meson_uart" : NULL;
257 }
258
259 /*
260  * This function is called only from probe() using a temporary io mapping
261  * in order to perform a reset before setting up the device. Since the
262  * temporarily mapped region was successfully requested, there can be no
263  * console on this port at this time. Hence it is not necessary for this
264  * function to acquire the port->lock. (Since there is no console on this
265  * port at this time, the port->lock is not initialized yet.)
266  */
267 static void meson_uart_reset(struct uart_port *port)
268 {
269         u32 val;
270
271         val = readl(port->membase + AML_UART_CONTROL);
272         val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
273         writel(val, port->membase + AML_UART_CONTROL);
274
275         val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
276         writel(val, port->membase + AML_UART_CONTROL);
277 }
278
279 static int meson_uart_startup(struct uart_port *port)
280 {
281         unsigned long flags;
282         u32 val;
283         int ret = 0;
284
285         uart_port_lock_irqsave(port, &flags);
286
287         val = readl(port->membase + AML_UART_CONTROL);
288         val |= AML_UART_CLEAR_ERR;
289         writel(val, port->membase + AML_UART_CONTROL);
290         val &= ~AML_UART_CLEAR_ERR;
291         writel(val, port->membase + AML_UART_CONTROL);
292
293         val |= (AML_UART_RX_EN | AML_UART_TX_EN);
294         writel(val, port->membase + AML_UART_CONTROL);
295
296         val |= (AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
297         writel(val, port->membase + AML_UART_CONTROL);
298
299         val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
300         writel(val, port->membase + AML_UART_MISC);
301
302         uart_port_unlock_irqrestore(port, flags);
303
304         ret = request_irq(port->irq, meson_uart_interrupt, 0,
305                           port->name, port);
306
307         return ret;
308 }
309
310 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
311 {
312         const struct meson_uart_data *private_data = port->private_data;
313         u32 val = 0;
314
315         while (!meson_uart_tx_empty(port))
316                 cpu_relax();
317
318         if (port->uartclk == 24000000) {
319                 unsigned int xtal_div = 3;
320
321                 if (private_data && private_data->has_xtal_div2) {
322                         xtal_div = 2;
323                         val |= AML_UART_BAUD_XTAL_DIV2;
324                 }
325                 val |= DIV_ROUND_CLOSEST(port->uartclk / xtal_div, baud) - 1;
326                 val |= AML_UART_BAUD_XTAL;
327         } else {
328                 val =  DIV_ROUND_CLOSEST(port->uartclk / 4, baud) - 1;
329         }
330         val |= AML_UART_BAUD_USE;
331         writel(val, port->membase + AML_UART_REG5);
332 }
333
334 static void meson_uart_set_termios(struct uart_port *port,
335                                    struct ktermios *termios,
336                                    const struct ktermios *old)
337 {
338         unsigned int cflags, iflags, baud;
339         unsigned long flags;
340         u32 val;
341
342         uart_port_lock_irqsave(port, &flags);
343
344         cflags = termios->c_cflag;
345         iflags = termios->c_iflag;
346
347         val = readl(port->membase + AML_UART_CONTROL);
348
349         val &= ~AML_UART_DATA_LEN_MASK;
350         switch (cflags & CSIZE) {
351         case CS8:
352                 val |= AML_UART_DATA_LEN_8BIT;
353                 break;
354         case CS7:
355                 val |= AML_UART_DATA_LEN_7BIT;
356                 break;
357         case CS6:
358                 val |= AML_UART_DATA_LEN_6BIT;
359                 break;
360         case CS5:
361                 val |= AML_UART_DATA_LEN_5BIT;
362                 break;
363         }
364
365         if (cflags & PARENB)
366                 val |= AML_UART_PARITY_EN;
367         else
368                 val &= ~AML_UART_PARITY_EN;
369
370         if (cflags & PARODD)
371                 val |= AML_UART_PARITY_TYPE;
372         else
373                 val &= ~AML_UART_PARITY_TYPE;
374
375         val &= ~AML_UART_STOP_BIT_LEN_MASK;
376         if (cflags & CSTOPB)
377                 val |= AML_UART_STOP_BIT_2SB;
378         else
379                 val |= AML_UART_STOP_BIT_1SB;
380
381         if (cflags & CRTSCTS) {
382                 if (port->flags & UPF_HARD_FLOW)
383                         val &= ~AML_UART_TWO_WIRE_EN;
384                 else
385                         termios->c_cflag &= ~CRTSCTS;
386         } else {
387                 val |= AML_UART_TWO_WIRE_EN;
388         }
389
390         writel(val, port->membase + AML_UART_CONTROL);
391
392         baud = uart_get_baud_rate(port, termios, old, 50, 4000000);
393         meson_uart_change_speed(port, baud);
394
395         port->read_status_mask = AML_UART_TX_FIFO_WERR;
396         if (iflags & INPCK)
397                 port->read_status_mask |= AML_UART_PARITY_ERR |
398                                           AML_UART_FRAME_ERR;
399
400         port->ignore_status_mask = 0;
401         if (iflags & IGNPAR)
402                 port->ignore_status_mask |= AML_UART_PARITY_ERR |
403                                             AML_UART_FRAME_ERR;
404
405         uart_update_timeout(port, termios->c_cflag, baud);
406         uart_port_unlock_irqrestore(port, flags);
407 }
408
409 static int meson_uart_verify_port(struct uart_port *port,
410                                   struct serial_struct *ser)
411 {
412         int ret = 0;
413
414         if (port->type != PORT_MESON)
415                 ret = -EINVAL;
416         if (port->irq != ser->irq)
417                 ret = -EINVAL;
418         if (ser->baud_base < 9600)
419                 ret = -EINVAL;
420         return ret;
421 }
422
423 static void meson_uart_release_port(struct uart_port *port)
424 {
425         devm_iounmap(port->dev, port->membase);
426         port->membase = NULL;
427         devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
428 }
429
430 static int meson_uart_request_port(struct uart_port *port)
431 {
432         if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
433                                      dev_name(port->dev))) {
434                 dev_err(port->dev, "Memory region busy\n");
435                 return -EBUSY;
436         }
437
438         port->membase = devm_ioremap(port->dev, port->mapbase,
439                                              port->mapsize);
440         if (!port->membase)
441                 return -ENOMEM;
442
443         return 0;
444 }
445
446 static void meson_uart_config_port(struct uart_port *port, int flags)
447 {
448         if (flags & UART_CONFIG_TYPE) {
449                 port->type = PORT_MESON;
450                 meson_uart_request_port(port);
451         }
452 }
453
454 #ifdef CONFIG_CONSOLE_POLL
455 /*
456  * Console polling routines for writing and reading from the uart while
457  * in an interrupt or debug context (i.e. kgdb).
458  */
459
460 static int meson_uart_poll_get_char(struct uart_port *port)
461 {
462         u32 c;
463         unsigned long flags;
464
465         uart_port_lock_irqsave(port, &flags);
466
467         if (readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)
468                 c = NO_POLL_CHAR;
469         else
470                 c = readl(port->membase + AML_UART_RFIFO);
471
472         uart_port_unlock_irqrestore(port, flags);
473
474         return c;
475 }
476
477 static void meson_uart_poll_put_char(struct uart_port *port, unsigned char c)
478 {
479         unsigned long flags;
480         u32 reg;
481         int ret;
482
483         uart_port_lock_irqsave(port, &flags);
484
485         /* Wait until FIFO is empty or timeout */
486         ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg,
487                                         reg & AML_UART_TX_EMPTY,
488                                         AML_UART_POLL_USEC,
489                                         AML_UART_TIMEOUT_USEC);
490         if (ret == -ETIMEDOUT) {
491                 dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n");
492                 goto out;
493         }
494
495         /* Write the character */
496         writel(c, port->membase + AML_UART_WFIFO);
497
498         /* Wait until FIFO is empty or timeout */
499         ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg,
500                                         reg & AML_UART_TX_EMPTY,
501                                         AML_UART_POLL_USEC,
502                                         AML_UART_TIMEOUT_USEC);
503         if (ret == -ETIMEDOUT)
504                 dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n");
505
506 out:
507         uart_port_unlock_irqrestore(port, flags);
508 }
509
510 #endif /* CONFIG_CONSOLE_POLL */
511
512 static const struct uart_ops meson_uart_ops = {
513         .set_mctrl      = meson_uart_set_mctrl,
514         .get_mctrl      = meson_uart_get_mctrl,
515         .tx_empty       = meson_uart_tx_empty,
516         .start_tx       = meson_uart_start_tx,
517         .stop_tx        = meson_uart_stop_tx,
518         .stop_rx        = meson_uart_stop_rx,
519         .startup        = meson_uart_startup,
520         .shutdown       = meson_uart_shutdown,
521         .set_termios    = meson_uart_set_termios,
522         .type           = meson_uart_type,
523         .config_port    = meson_uart_config_port,
524         .request_port   = meson_uart_request_port,
525         .release_port   = meson_uart_release_port,
526         .verify_port    = meson_uart_verify_port,
527 #ifdef CONFIG_CONSOLE_POLL
528         .poll_get_char  = meson_uart_poll_get_char,
529         .poll_put_char  = meson_uart_poll_put_char,
530 #endif
531 };
532
533 #ifdef CONFIG_SERIAL_MESON_CONSOLE
534 static void meson_uart_enable_tx_engine(struct uart_port *port)
535 {
536         u32 val;
537
538         val = readl(port->membase + AML_UART_CONTROL);
539         val |= AML_UART_TX_EN;
540         writel(val, port->membase + AML_UART_CONTROL);
541 }
542
543 static void meson_console_putchar(struct uart_port *port, unsigned char ch)
544 {
545         if (!port->membase)
546                 return;
547
548         while (readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)
549                 cpu_relax();
550         writel(ch, port->membase + AML_UART_WFIFO);
551 }
552
553 static void meson_serial_port_write(struct uart_port *port, const char *s,
554                                     u_int count)
555 {
556         unsigned long flags;
557         int locked = 1;
558         u32 val, tmp;
559
560         if (oops_in_progress)
561                 locked = uart_port_trylock_irqsave(port, &flags);
562         else
563                 uart_port_lock_irqsave(port, &flags);
564
565         val = readl(port->membase + AML_UART_CONTROL);
566         tmp = val & ~(AML_UART_TX_INT_EN | AML_UART_RX_INT_EN);
567         writel(tmp, port->membase + AML_UART_CONTROL);
568
569         uart_console_write(port, s, count, meson_console_putchar);
570         writel(val, port->membase + AML_UART_CONTROL);
571
572         if (locked)
573                 uart_port_unlock_irqrestore(port, flags);
574 }
575
576 static void meson_serial_console_write(struct console *co, const char *s,
577                                        u_int count)
578 {
579         struct uart_port *port;
580
581         port = meson_ports[co->index];
582         if (!port)
583                 return;
584
585         meson_serial_port_write(port, s, count);
586 }
587
588 static int meson_serial_console_setup(struct console *co, char *options)
589 {
590         struct uart_port *port;
591         int baud = 115200;
592         int bits = 8;
593         int parity = 'n';
594         int flow = 'n';
595
596         if (co->index < 0 || co->index >= AML_UART_PORT_NUM)
597                 return -EINVAL;
598
599         port = meson_ports[co->index];
600         if (!port || !port->membase)
601                 return -ENODEV;
602
603         meson_uart_enable_tx_engine(port);
604
605         if (options)
606                 uart_parse_options(options, &baud, &parity, &bits, &flow);
607
608         return uart_set_options(port, co, baud, parity, bits, flow);
609 }
610
611 #define MESON_SERIAL_CONSOLE(_devname)                                  \
612         static struct console meson_serial_console_##_devname = {       \
613                 .name           = __stringify(_devname),                \
614                 .write          = meson_serial_console_write,           \
615                 .device         = uart_console_device,                  \
616                 .setup          = meson_serial_console_setup,           \
617                 .flags          = CON_PRINTBUFFER,                      \
618                 .index          = -1,                                   \
619                 .data           = &meson_uart_driver_##_devname,        \
620         }
621
622 MESON_SERIAL_CONSOLE(ttyAML);
623 MESON_SERIAL_CONSOLE(ttyS);
624
625 static void meson_serial_early_console_write(struct console *co,
626                                              const char *s,
627                                              u_int count)
628 {
629         struct earlycon_device *dev = co->data;
630
631         meson_serial_port_write(&dev->port, s, count);
632 }
633
634 static int __init
635 meson_serial_early_console_setup(struct earlycon_device *device, const char *opt)
636 {
637         if (!device->port.membase)
638                 return -ENODEV;
639
640         meson_uart_enable_tx_engine(&device->port);
641         device->con->write = meson_serial_early_console_write;
642         return 0;
643 }
644
645 OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", meson_serial_early_console_setup);
646 OF_EARLYCON_DECLARE(meson, "amlogic,meson-s4-uart", meson_serial_early_console_setup);
647
648 #define MESON_SERIAL_CONSOLE_PTR(_devname) (&meson_serial_console_##_devname)
649 #else
650 #define MESON_SERIAL_CONSOLE_PTR(_devname) (NULL)
651 #endif
652
653 #define MESON_UART_DRIVER(_devname)                                     \
654         static struct uart_driver meson_uart_driver_##_devname = {      \
655                 .owner          = THIS_MODULE,                          \
656                 .driver_name    = "meson_uart",                         \
657                 .dev_name       = __stringify(_devname),                \
658                 .nr             = AML_UART_PORT_NUM,                    \
659                 .cons           = MESON_SERIAL_CONSOLE_PTR(_devname),   \
660         }
661
662 MESON_UART_DRIVER(ttyAML);
663 MESON_UART_DRIVER(ttyS);
664
665 static int meson_uart_probe_clocks(struct platform_device *pdev,
666                                    struct uart_port *port)
667 {
668         struct clk *clk_xtal = NULL;
669         struct clk *clk_pclk = NULL;
670         struct clk *clk_baud = NULL;
671
672         clk_pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
673         if (IS_ERR(clk_pclk))
674                 return PTR_ERR(clk_pclk);
675
676         clk_xtal = devm_clk_get_enabled(&pdev->dev, "xtal");
677         if (IS_ERR(clk_xtal))
678                 return PTR_ERR(clk_xtal);
679
680         clk_baud = devm_clk_get_enabled(&pdev->dev, "baud");
681         if (IS_ERR(clk_baud))
682                 return PTR_ERR(clk_baud);
683
684         port->uartclk = clk_get_rate(clk_baud);
685
686         return 0;
687 }
688
689 static struct uart_driver *meson_uart_current(const struct meson_uart_data *pd)
690 {
691         return (pd && pd->uart_driver) ?
692                 pd->uart_driver : &meson_uart_driver_ttyAML;
693 }
694
695 static int meson_uart_probe(struct platform_device *pdev)
696 {
697         const struct meson_uart_data *priv_data;
698         struct uart_driver *uart_driver;
699         struct resource *res_mem;
700         struct uart_port *port;
701         u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
702         int ret = 0;
703         int irq;
704         bool has_rtscts;
705
706         if (pdev->dev.of_node)
707                 pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
708
709         if (pdev->id < 0) {
710                 int id;
711
712                 for (id = AML_UART_PORT_OFFSET; id < AML_UART_PORT_NUM; id++) {
713                         if (!meson_ports[id]) {
714                                 pdev->id = id;
715                                 break;
716                         }
717                 }
718         }
719
720         if (pdev->id < 0 || pdev->id >= AML_UART_PORT_NUM)
721                 return -EINVAL;
722
723         res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
724         if (!res_mem)
725                 return -ENODEV;
726
727         irq = platform_get_irq(pdev, 0);
728         if (irq < 0)
729                 return irq;
730
731         of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize);
732         has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts");
733
734         if (meson_ports[pdev->id]) {
735                 return dev_err_probe(&pdev->dev, -EBUSY,
736                                      "port %d already allocated\n", pdev->id);
737         }
738
739         port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
740         if (!port)
741                 return -ENOMEM;
742
743         ret = meson_uart_probe_clocks(pdev, port);
744         if (ret)
745                 return ret;
746
747         priv_data = device_get_match_data(&pdev->dev);
748
749         uart_driver = meson_uart_current(priv_data);
750
751         if (!uart_driver->state) {
752                 ret = uart_register_driver(uart_driver);
753                 if (ret)
754                         return dev_err_probe(&pdev->dev, ret,
755                                              "can't register uart driver\n");
756         }
757
758         port->iotype = UPIO_MEM;
759         port->mapbase = res_mem->start;
760         port->mapsize = resource_size(res_mem);
761         port->irq = irq;
762         port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY;
763         if (has_rtscts)
764                 port->flags |= UPF_HARD_FLOW;
765         port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE);
766         port->dev = &pdev->dev;
767         port->line = pdev->id;
768         port->type = PORT_MESON;
769         port->x_char = 0;
770         port->ops = &meson_uart_ops;
771         port->fifosize = fifosize;
772         port->private_data = (void *)priv_data;
773
774         meson_ports[pdev->id] = port;
775         platform_set_drvdata(pdev, port);
776
777         /* reset port before registering (and possibly registering console) */
778         if (meson_uart_request_port(port) >= 0) {
779                 meson_uart_reset(port);
780                 meson_uart_release_port(port);
781         }
782
783         ret = uart_add_one_port(uart_driver, port);
784         if (ret)
785                 meson_ports[pdev->id] = NULL;
786
787         return ret;
788 }
789
790 static void meson_uart_remove(struct platform_device *pdev)
791 {
792         struct uart_driver *uart_driver;
793         struct uart_port *port;
794
795         port = platform_get_drvdata(pdev);
796         uart_driver = meson_uart_current(port->private_data);
797         uart_remove_one_port(uart_driver, port);
798         meson_ports[pdev->id] = NULL;
799
800         for (int id = 0; id < AML_UART_PORT_NUM; id++)
801                 if (meson_ports[id])
802                         return;
803
804         /* No more available uart ports, unregister uart driver */
805         uart_unregister_driver(uart_driver);
806 }
807
808 static struct meson_uart_data meson_g12a_uart_data = {
809         .has_xtal_div2 = true,
810 };
811
812 static struct meson_uart_data meson_a1_uart_data = {
813         .uart_driver = &meson_uart_driver_ttyS,
814         .has_xtal_div2 = false,
815 };
816
817 static struct meson_uart_data meson_s4_uart_data = {
818         .uart_driver = &meson_uart_driver_ttyS,
819         .has_xtal_div2 = true,
820 };
821
822 static const struct of_device_id meson_uart_dt_match[] = {
823         { .compatible = "amlogic,meson6-uart" },
824         { .compatible = "amlogic,meson8-uart" },
825         { .compatible = "amlogic,meson8b-uart" },
826         { .compatible = "amlogic,meson-gx-uart" },
827         {
828                 .compatible = "amlogic,meson-g12a-uart",
829                 .data = (void *)&meson_g12a_uart_data,
830         },
831         {
832                 .compatible = "amlogic,meson-s4-uart",
833                 .data = (void *)&meson_s4_uart_data,
834         },
835         {
836                 .compatible = "amlogic,meson-a1-uart",
837                 .data = (void *)&meson_a1_uart_data,
838         },
839         { /* sentinel */ },
840 };
841 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
842
843 static  struct platform_driver meson_uart_platform_driver = {
844         .probe          = meson_uart_probe,
845         .remove         = meson_uart_remove,
846         .driver         = {
847                 .name           = "meson_uart",
848                 .of_match_table = meson_uart_dt_match,
849         },
850 };
851
852 module_platform_driver(meson_uart_platform_driver);
853
854 MODULE_AUTHOR("Carlo Caione <[email protected]>");
855 MODULE_DESCRIPTION("Amlogic Meson serial port driver");
856 MODULE_LICENSE("GPL v2");
This page took 0.078739 seconds and 4 git commands to generate.