1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for GRLIB serial ports (APBUART)
5 * Based on linux/drivers/serial/amba.c
7 * Copyright (C) 2000 Deep Blue Solutions Ltd.
8 * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de>
9 * Copyright (C) 2006 Daniel Hellstrom <daniel@gaisler.com>, Aeroflex Gaisler AB
10 * Copyright (C) 2008 Gilead Kutnick <kutnickg@zin-tech.com>
11 * Copyright (C) 2009 Kristoffer Glembo <kristoffer@gaisler.com>, Aeroflex Gaisler AB
14 #include <linux/module.h>
15 #include <linux/tty.h>
16 #include <linux/tty_flip.h>
17 #include <linux/ioport.h>
18 #include <linux/init.h>
19 #include <linux/serial.h>
20 #include <linux/console.h>
21 #include <linux/sysrq.h>
22 #include <linux/kthread.h>
23 #include <linux/device.h>
25 #include <linux/platform_device.h>
27 #include <linux/serial_core.h>
32 #define SERIAL_APBUART_MAJOR TTY_MAJOR
33 #define SERIAL_APBUART_MINOR 64
34 #define UART_DUMMY_RSR_RX 0x8000 /* for ignore all read */
36 static void apbuart_tx_chars(struct uart_port
*port
);
38 static void apbuart_stop_tx(struct uart_port
*port
)
42 cr
= UART_GET_CTRL(port
);
44 UART_PUT_CTRL(port
, cr
);
47 static void apbuart_start_tx(struct uart_port
*port
)
51 cr
= UART_GET_CTRL(port
);
53 UART_PUT_CTRL(port
, cr
);
55 if (UART_GET_STATUS(port
) & UART_STATUS_THE
)
56 apbuart_tx_chars(port
);
59 static void apbuart_stop_rx(struct uart_port
*port
)
63 cr
= UART_GET_CTRL(port
);
64 cr
&= ~(UART_CTRL_RI
);
65 UART_PUT_CTRL(port
, cr
);
68 static void apbuart_rx_chars(struct uart_port
*port
)
70 unsigned int status
, rsr
;
71 unsigned int max_chars
= port
->fifosize
;
74 status
= UART_GET_STATUS(port
);
76 while (UART_RX_DATA(status
) && (max_chars
--)) {
78 ch
= UART_GET_CHAR(port
);
83 rsr
= UART_GET_STATUS(port
) | UART_DUMMY_RSR_RX
;
84 UART_PUT_STATUS(port
, 0);
85 if (rsr
& UART_STATUS_ERR
) {
87 if (rsr
& UART_STATUS_BR
) {
88 rsr
&= ~(UART_STATUS_FE
| UART_STATUS_PE
);
90 if (uart_handle_break(port
))
92 } else if (rsr
& UART_STATUS_PE
) {
93 port
->icount
.parity
++;
94 } else if (rsr
& UART_STATUS_FE
) {
97 if (rsr
& UART_STATUS_OE
)
98 port
->icount
.overrun
++;
100 rsr
&= port
->read_status_mask
;
102 if (rsr
& UART_STATUS_PE
)
104 else if (rsr
& UART_STATUS_FE
)
108 if (uart_handle_sysrq_char(port
, ch
))
111 uart_insert_char(port
, rsr
, UART_STATUS_OE
, ch
, flag
);
115 status
= UART_GET_STATUS(port
);
118 tty_flip_buffer_push(&port
->state
->port
);
121 static void apbuart_tx_chars(struct uart_port
*port
)
125 uart_port_tx_limited(port
, ch
, port
->fifosize
,
127 UART_PUT_CHAR(port
, ch
),
131 static irqreturn_t
apbuart_int(int irq
, void *dev_id
)
133 struct uart_port
*port
= dev_id
;
136 uart_port_lock(port
);
138 status
= UART_GET_STATUS(port
);
139 if (status
& UART_STATUS_DR
)
140 apbuart_rx_chars(port
);
141 if (status
& UART_STATUS_THE
)
142 apbuart_tx_chars(port
);
144 uart_port_unlock(port
);
149 static unsigned int apbuart_tx_empty(struct uart_port
*port
)
151 unsigned int status
= UART_GET_STATUS(port
);
152 return status
& UART_STATUS_THE
? TIOCSER_TEMT
: 0;
155 static unsigned int apbuart_get_mctrl(struct uart_port
*port
)
157 /* The GRLIB APBUART handles flow control in hardware */
158 return TIOCM_CAR
| TIOCM_DSR
| TIOCM_CTS
;
161 static void apbuart_set_mctrl(struct uart_port
*port
, unsigned int mctrl
)
163 /* The GRLIB APBUART handles flow control in hardware */
166 static void apbuart_break_ctl(struct uart_port
*port
, int break_state
)
168 /* We don't support sending break */
171 static int apbuart_startup(struct uart_port
*port
)
176 /* Allocate the IRQ */
177 retval
= request_irq(port
->irq
, apbuart_int
, 0, "apbuart", port
);
181 /* Finally, enable interrupts */
182 cr
= UART_GET_CTRL(port
);
184 cr
| UART_CTRL_RE
| UART_CTRL_TE
|
185 UART_CTRL_RI
| UART_CTRL_TI
);
190 static void apbuart_shutdown(struct uart_port
*port
)
194 /* disable all interrupts, disable the port */
195 cr
= UART_GET_CTRL(port
);
197 cr
& ~(UART_CTRL_RE
| UART_CTRL_TE
|
198 UART_CTRL_RI
| UART_CTRL_TI
));
200 /* Free the interrupt */
201 free_irq(port
->irq
, port
);
204 static void apbuart_set_termios(struct uart_port
*port
,
205 struct ktermios
*termios
, const struct ktermios
*old
)
209 unsigned int baud
, quot
;
211 /* Ask the core to calculate the divisor for us. */
212 baud
= uart_get_baud_rate(port
, termios
, old
, 0, port
->uartclk
/ 16);
214 panic("invalid baudrate %i\n", port
->uartclk
/ 16);
216 /* uart_get_divisor calc a *16 uart freq, apbuart is *8 */
217 quot
= (uart_get_divisor(port
, baud
)) * 2;
218 cr
= UART_GET_CTRL(port
);
219 cr
&= ~(UART_CTRL_PE
| UART_CTRL_PS
);
221 if (termios
->c_cflag
& PARENB
) {
223 if ((termios
->c_cflag
& PARODD
))
227 /* Enable flow control. */
228 if (termios
->c_cflag
& CRTSCTS
)
231 uart_port_lock_irqsave(port
, &flags
);
233 /* Update the per-port timeout. */
234 uart_update_timeout(port
, termios
->c_cflag
, baud
);
236 port
->read_status_mask
= UART_STATUS_OE
;
237 if (termios
->c_iflag
& INPCK
)
238 port
->read_status_mask
|= UART_STATUS_FE
| UART_STATUS_PE
;
240 /* Characters to ignore */
241 port
->ignore_status_mask
= 0;
242 if (termios
->c_iflag
& IGNPAR
)
243 port
->ignore_status_mask
|= UART_STATUS_FE
| UART_STATUS_PE
;
245 /* Ignore all characters if CREAD is not set. */
246 if ((termios
->c_cflag
& CREAD
) == 0)
247 port
->ignore_status_mask
|= UART_DUMMY_RSR_RX
;
251 UART_PUT_SCAL(port
, quot
);
252 UART_PUT_CTRL(port
, cr
);
254 uart_port_unlock_irqrestore(port
, flags
);
257 static const char *apbuart_type(struct uart_port
*port
)
259 return port
->type
== PORT_APBUART
? "GRLIB/APBUART" : NULL
;
262 static void apbuart_release_port(struct uart_port
*port
)
264 release_mem_region(port
->mapbase
, 0x100);
267 static int apbuart_request_port(struct uart_port
*port
)
269 return request_mem_region(port
->mapbase
, 0x100, "grlib-apbuart")
270 != NULL
? 0 : -EBUSY
;
274 /* Configure/autoconfigure the port */
275 static void apbuart_config_port(struct uart_port
*port
, int flags
)
277 if (flags
& UART_CONFIG_TYPE
) {
278 port
->type
= PORT_APBUART
;
279 apbuart_request_port(port
);
283 /* Verify the new serial_struct (for TIOCSSERIAL) */
284 static int apbuart_verify_port(struct uart_port
*port
,
285 struct serial_struct
*ser
)
288 if (ser
->type
!= PORT_UNKNOWN
&& ser
->type
!= PORT_APBUART
)
290 if (ser
->irq
< 0 || ser
->irq
>= NR_IRQS
)
292 if (ser
->baud_base
< 9600)
297 static const struct uart_ops grlib_apbuart_ops
= {
298 .tx_empty
= apbuart_tx_empty
,
299 .set_mctrl
= apbuart_set_mctrl
,
300 .get_mctrl
= apbuart_get_mctrl
,
301 .stop_tx
= apbuart_stop_tx
,
302 .start_tx
= apbuart_start_tx
,
303 .stop_rx
= apbuart_stop_rx
,
304 .break_ctl
= apbuart_break_ctl
,
305 .startup
= apbuart_startup
,
306 .shutdown
= apbuart_shutdown
,
307 .set_termios
= apbuart_set_termios
,
308 .type
= apbuart_type
,
309 .release_port
= apbuart_release_port
,
310 .request_port
= apbuart_request_port
,
311 .config_port
= apbuart_config_port
,
312 .verify_port
= apbuart_verify_port
,
315 static struct uart_port grlib_apbuart_ports
[UART_NR
];
316 static struct device_node
*grlib_apbuart_nodes
[UART_NR
];
318 static int apbuart_scan_fifo_size(struct uart_port
*port
, int portnumber
)
325 ctrl
= UART_GET_CTRL(port
);
328 * Enable the transceiver and wait for it to be ready to send data.
329 * Clear interrupts so that this process will not be externally
330 * interrupted in the middle (which can cause the transceiver to
331 * drain prematurely).
334 local_irq_save(flags
);
336 UART_PUT_CTRL(port
, ctrl
| UART_CTRL_TE
);
338 while (!UART_TX_READY(UART_GET_STATUS(port
)))
342 * Disable the transceiver so data isn't actually sent during the
346 UART_PUT_CTRL(port
, ctrl
& ~(UART_CTRL_TE
));
349 UART_PUT_CHAR(port
, 0);
352 * So long as transmitting a character increments the tranceivier FIFO
353 * length the FIFO must be at least that big. These bytes will
354 * automatically drain off of the FIFO.
357 status
= UART_GET_STATUS(port
);
358 while (((status
>> 20) & 0x3F) == fifosize
) {
360 UART_PUT_CHAR(port
, 0);
361 status
= UART_GET_STATUS(port
);
366 UART_PUT_CTRL(port
, ctrl
);
367 local_irq_restore(flags
);
375 static void apbuart_flush_fifo(struct uart_port
*port
)
379 for (i
= 0; i
< port
->fifosize
; i
++)
384 /* ======================================================================== */
385 /* Console driver, if enabled */
386 /* ======================================================================== */
388 #ifdef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
390 static void apbuart_console_putchar(struct uart_port
*port
, unsigned char ch
)
394 status
= UART_GET_STATUS(port
);
395 } while (!UART_TX_READY(status
));
396 UART_PUT_CHAR(port
, ch
);
400 apbuart_console_write(struct console
*co
, const char *s
, unsigned int count
)
402 struct uart_port
*port
= &grlib_apbuart_ports
[co
->index
];
403 unsigned int status
, old_cr
, new_cr
;
405 /* First save the CR then disable the interrupts */
406 old_cr
= UART_GET_CTRL(port
);
407 new_cr
= old_cr
& ~(UART_CTRL_RI
| UART_CTRL_TI
);
408 UART_PUT_CTRL(port
, new_cr
);
410 uart_console_write(port
, s
, count
, apbuart_console_putchar
);
413 * Finally, wait for transmitter to become empty
414 * and restore the TCR
417 status
= UART_GET_STATUS(port
);
418 } while (!UART_TX_READY(status
));
419 UART_PUT_CTRL(port
, old_cr
);
423 apbuart_console_get_options(struct uart_port
*port
, int *baud
,
424 int *parity
, int *bits
)
426 if (UART_GET_CTRL(port
) & (UART_CTRL_RE
| UART_CTRL_TE
)) {
428 unsigned int quot
, status
;
429 status
= UART_GET_STATUS(port
);
432 if (status
& UART_CTRL_PE
) {
433 if ((status
& UART_CTRL_PS
) == 0)
440 quot
= UART_GET_SCAL(port
) / 8;
441 *baud
= port
->uartclk
/ (16 * (quot
+ 1));
445 static int __init
apbuart_console_setup(struct console
*co
, char *options
)
447 struct uart_port
*port
;
453 pr_debug("apbuart_console_setup co=%p, co->index=%i, options=%s\n",
454 co
, co
->index
, options
);
457 * Check whether an invalid uart number has been specified, and
458 * if so, search for the first available port that does have
461 if (co
->index
>= grlib_apbuart_port_nr
)
464 port
= &grlib_apbuart_ports
[co
->index
];
466 spin_lock_init(&port
->lock
);
469 uart_parse_options(options
, &baud
, &parity
, &bits
, &flow
);
471 apbuart_console_get_options(port
, &baud
, &parity
, &bits
);
473 return uart_set_options(port
, co
, baud
, parity
, bits
, flow
);
476 static struct uart_driver grlib_apbuart_driver
;
478 static struct console grlib_apbuart_console
= {
480 .write
= apbuart_console_write
,
481 .device
= uart_console_device
,
482 .setup
= apbuart_console_setup
,
483 .flags
= CON_PRINTBUFFER
,
485 .data
= &grlib_apbuart_driver
,
489 static int grlib_apbuart_configure(void);
491 static int __init
apbuart_console_init(void)
493 if (grlib_apbuart_configure())
495 register_console(&grlib_apbuart_console
);
499 console_initcall(apbuart_console_init
);
501 #define APBUART_CONSOLE (&grlib_apbuart_console)
503 #define APBUART_CONSOLE NULL
506 static struct uart_driver grlib_apbuart_driver
= {
507 .owner
= THIS_MODULE
,
508 .driver_name
= "serial",
510 .major
= SERIAL_APBUART_MAJOR
,
511 .minor
= SERIAL_APBUART_MINOR
,
513 .cons
= APBUART_CONSOLE
,
517 /* ======================================================================== */
518 /* OF Platform Driver */
519 /* ======================================================================== */
521 static int apbuart_probe(struct platform_device
*op
)
524 struct uart_port
*port
= NULL
;
526 for (i
= 0; i
< grlib_apbuart_port_nr
; i
++) {
527 if (op
->dev
.of_node
== grlib_apbuart_nodes
[i
])
531 port
= &grlib_apbuart_ports
[i
];
532 port
->dev
= &op
->dev
;
533 port
->irq
= op
->archdata
.irqs
[0];
535 uart_add_one_port(&grlib_apbuart_driver
, (struct uart_port
*) port
);
537 apbuart_flush_fifo((struct uart_port
*) port
);
539 printk(KERN_INFO
"grlib-apbuart at 0x%llx, irq %d\n",
540 (unsigned long long) port
->mapbase
, port
->irq
);
544 static const struct of_device_id apbuart_match
[] = {
546 .name
= "GAISLER_APBUART",
553 MODULE_DEVICE_TABLE(of
, apbuart_match
);
555 static struct platform_driver grlib_apbuart_of_driver
= {
556 .probe
= apbuart_probe
,
558 .name
= "grlib-apbuart",
559 .of_match_table
= apbuart_match
,
564 static int __init
grlib_apbuart_configure(void)
566 struct device_node
*np
;
569 for_each_matching_node(np
, apbuart_match
) {
572 const struct amba_prom_registers
*regs
;
573 struct uart_port
*port
;
576 ampopts
= of_get_property(np
, "ampopts", NULL
);
577 if (ampopts
&& (*ampopts
== 0))
578 continue; /* Ignore if used by another OS instance */
579 regs
= of_get_property(np
, "reg", NULL
);
580 /* Frequency of APB Bus is frequency of UART */
581 freq_hz
= of_get_property(np
, "freq", NULL
);
583 if (!regs
|| !freq_hz
|| (*freq_hz
== 0))
586 grlib_apbuart_nodes
[line
] = np
;
588 addr
= regs
->phys_addr
;
590 port
= &grlib_apbuart_ports
[line
];
592 port
->mapbase
= addr
;
593 port
->membase
= ioremap(addr
, sizeof(struct grlib_apbuart_regs_map
));
595 port
->iotype
= UPIO_MEM
;
596 port
->ops
= &grlib_apbuart_ops
;
597 port
->has_sysrq
= IS_ENABLED(CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
);
598 port
->flags
= UPF_BOOT_AUTOCONF
;
600 port
->uartclk
= *freq_hz
;
601 port
->fifosize
= apbuart_scan_fifo_size((struct uart_port
*) port
, line
);
604 /* We support maximum UART_NR uarts ... */
609 grlib_apbuart_driver
.nr
= grlib_apbuart_port_nr
= line
;
610 return line
? 0 : -ENODEV
;
613 static int __init
grlib_apbuart_init(void)
617 /* Find all APBUARTS in device the tree and initialize their ports */
618 ret
= grlib_apbuart_configure();
622 printk(KERN_INFO
"Serial: GRLIB APBUART driver\n");
624 ret
= uart_register_driver(&grlib_apbuart_driver
);
627 printk(KERN_ERR
"%s: uart_register_driver failed (%i)\n",
632 ret
= platform_driver_register(&grlib_apbuart_of_driver
);
635 "%s: platform_driver_register failed (%i)\n",
637 uart_unregister_driver(&grlib_apbuart_driver
);
644 static void __exit
grlib_apbuart_exit(void)
648 for (i
= 0; i
< grlib_apbuart_port_nr
; i
++)
649 uart_remove_one_port(&grlib_apbuart_driver
,
650 &grlib_apbuart_ports
[i
]);
652 uart_unregister_driver(&grlib_apbuart_driver
);
653 platform_driver_unregister(&grlib_apbuart_of_driver
);
656 module_init(grlib_apbuart_init
);
657 module_exit(grlib_apbuart_exit
);
659 MODULE_AUTHOR("Aeroflex Gaisler AB");
660 MODULE_DESCRIPTION("GRLIB APBUART serial driver");
661 MODULE_VERSION("2.1");
662 MODULE_LICENSE("GPL");