Lines Matching +full:sp7021 +full:- +full:reset

1 // SPDX-License-Identifier: GPL-2.0
7 * Note1: This driver is 8250-like uart, but are not register compatible.
28 #include <linux/reset.h>
82 writel(ch, port->membase + SUP_UART_DATA); in sp_uart_put_char()
87 unsigned int lsr = readl(port->membase + SUP_UART_LSR); in sunplus_tx_buf_not_full()
94 unsigned int lsr = readl(port->membase + SUP_UART_LSR); in sunplus_tx_empty()
101 unsigned int mcr = readl(port->membase + SUP_UART_MCR); in sunplus_set_mctrl()
128 writel(mcr, port->membase + SUP_UART_MCR); in sunplus_set_mctrl()
135 mcr = readl(port->membase + SUP_UART_MCR); in sunplus_get_mctrl()
159 isc = readl(port->membase + SUP_UART_ISC); in sunplus_stop_tx()
161 writel(isc, port->membase + SUP_UART_ISC); in sunplus_stop_tx()
168 isc = readl(port->membase + SUP_UART_ISC); in sunplus_start_tx()
170 writel(isc, port->membase + SUP_UART_ISC); in sunplus_start_tx()
177 isc = readl(port->membase + SUP_UART_ISC); in sunplus_stop_rx()
179 writel(isc, port->membase + SUP_UART_ISC); in sunplus_stop_rx()
189 lcr = readl(port->membase + SUP_UART_LCR); in sunplus_break_ctl()
196 writel(lcr, port->membase + SUP_UART_LCR); in sunplus_break_ctl()
203 struct tty_port *tport = &port->state->port; in transmit_chars()
205 if (port->x_char) { in transmit_chars()
206 sp_uart_put_char(port, port->x_char); in transmit_chars()
207 port->icount.tx++; in transmit_chars()
208 port->x_char = 0; in transmit_chars()
212 if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) { in transmit_chars()
226 if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) in transmit_chars()
229 if (kfifo_is_empty(&tport->xmit_fifo)) in transmit_chars()
235 unsigned int lsr = readl(port->membase + SUP_UART_LSR); in receive_chars()
239 ch = readl(port->membase + SUP_UART_DATA); in receive_chars()
241 port->icount.rx++; in receive_chars()
246 port->icount.brk++; in receive_chars()
251 port->icount.parity++; in receive_chars()
254 port->icount.frame++; in receive_chars()
259 port->icount.overrun++; in receive_chars()
262 if (port->ignore_status_mask & SUP_DUMMY_READ) in receive_chars()
271 lsr = readl(port->membase + SUP_UART_LSR); in receive_chars()
274 tty_flip_buffer_push(&port->state->port); in receive_chars()
284 isc = readl(port->membase + SUP_UART_ISC); in sunplus_uart_irq()
303 ret = request_irq(port->irq, sunplus_uart_irq, 0, "sunplus_uart", port); in sunplus_startup()
313 writel(isc, port->membase + SUP_UART_ISC); in sunplus_startup()
328 writel(0, port->membase + SUP_UART_ISC); /* disable all interrupt */ in sunplus_shutdown()
331 free_irq(port->irq, port); in sunplus_shutdown()
339 u32 clk = port->uartclk; in sunplus_set_termios()
342 baud = uart_get_baud_rate(port, termios, oldtermios, 0, port->uartclk / 16); in sunplus_set_termios()
348 div = (div >> 4) - 1; in sunplus_set_termios()
352 switch (termios->c_cflag & CSIZE) { in sunplus_set_termios()
367 if (termios->c_cflag & CSTOPB) in sunplus_set_termios()
370 if (termios->c_cflag & PARENB) { in sunplus_set_termios()
373 if (!(termios->c_cflag & PARODD)) in sunplus_set_termios()
379 uart_update_timeout(port, termios->c_cflag, baud); in sunplus_set_termios()
381 port->read_status_mask = 0; in sunplus_set_termios()
382 if (termios->c_iflag & INPCK) in sunplus_set_termios()
383 port->read_status_mask |= SUP_UART_LSR_PE | SUP_UART_LSR_FE; in sunplus_set_termios()
385 if (termios->c_iflag & (BRKINT | PARMRK)) in sunplus_set_termios()
386 port->read_status_mask |= SUP_UART_LSR_BC; in sunplus_set_termios()
389 port->ignore_status_mask = 0; in sunplus_set_termios()
390 if (termios->c_iflag & IGNPAR) in sunplus_set_termios()
391 port->ignore_status_mask |= SUP_UART_LSR_FE | SUP_UART_LSR_PE; in sunplus_set_termios()
393 if (termios->c_iflag & IGNBRK) { in sunplus_set_termios()
394 port->ignore_status_mask |= SUP_UART_LSR_BC; in sunplus_set_termios()
396 if (termios->c_iflag & IGNPAR) in sunplus_set_termios()
397 port->ignore_status_mask |= SUP_UART_LSR_OE; in sunplus_set_termios()
401 if ((termios->c_cflag & CREAD) == 0) { in sunplus_set_termios()
402 port->ignore_status_mask |= SUP_DUMMY_READ; in sunplus_set_termios()
404 writel(0, port->membase + SUP_UART_RX_RESIDUE); in sunplus_set_termios()
408 writel(div_h, port->membase + SUP_UART_DIV_H); in sunplus_set_termios()
409 writel(div_l, port->membase + SUP_UART_DIV_L); in sunplus_set_termios()
410 writel(lcr, port->membase + SUP_UART_LCR); in sunplus_set_termios()
417 int new = termios->c_line; in sunplus_set_ldisc()
420 port->flags |= UPF_HARDPPS_CD; in sunplus_set_ldisc()
422 port->flags &= ~UPF_HARDPPS_CD; in sunplus_set_ldisc()
427 return port->type == PORT_SUNPLUS ? "sunplus_uart" : NULL; in sunplus_type()
433 port->type = PORT_SUNPLUS; in sunplus_config_port()
438 if (ser->type != PORT_UNKNOWN && ser->type != PORT_SUNPLUS) in sunplus_verify_port()
439 return -EINVAL; in sunplus_verify_port()
451 ret = readl_poll_timeout_atomic(port->membase + SUP_UART_LSR, val, in wait_for_xmitr()
454 if (ret == -ETIMEDOUT) { in wait_for_xmitr()
455 dev_err(port->dev, "Timeout waiting while UART TX FULL\n"); in wait_for_xmitr()
470 unsigned int lsr = readl(port->membase + SUP_UART_LSR); in sunplus_poll_get_char()
475 return readl(port->membase + SUP_UART_DATA); in sunplus_poll_get_char()
518 locked = uart_port_trylock_irqsave(&sunplus_console_ports[co->index]->port, &flags); in sunplus_console_write()
520 uart_port_lock_irqsave(&sunplus_console_ports[co->index]->port, &flags); in sunplus_console_write()
522 uart_console_write(&sunplus_console_ports[co->index]->port, s, count, in sunplus_console_write()
526 uart_port_unlock_irqrestore(&sunplus_console_ports[co->index]->port, flags); in sunplus_console_write()
537 if (co->index < 0 || co->index >= SUP_UART_NR) in sunplus_console_setup()
538 return -EINVAL; in sunplus_console_setup()
540 sup = sunplus_console_ports[co->index]; in sunplus_console_setup()
542 return -ENODEV; in sunplus_console_setup()
547 return uart_set_options(&sup->port, co, baud, parity, bits, flow); in sunplus_console_setup()
557 .index = -1,
593 pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); in sunplus_uart_probe()
595 if (pdev->id < 0 || pdev->id >= SUP_UART_NR) in sunplus_uart_probe()
596 return -EINVAL; in sunplus_uart_probe()
598 sup = devm_kzalloc(&pdev->dev, sizeof(*sup), GFP_KERNEL); in sunplus_uart_probe()
600 return -ENOMEM; in sunplus_uart_probe()
602 sup->clk = devm_clk_get_optional(&pdev->dev, NULL); in sunplus_uart_probe()
603 if (IS_ERR(sup->clk)) in sunplus_uart_probe()
604 return dev_err_probe(&pdev->dev, PTR_ERR(sup->clk), "clk not found\n"); in sunplus_uart_probe()
606 ret = clk_prepare_enable(sup->clk); in sunplus_uart_probe()
610 ret = devm_add_action_or_reset(&pdev->dev, sunplus_uart_disable_unprepare, sup->clk); in sunplus_uart_probe()
614 sup->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); in sunplus_uart_probe()
615 if (IS_ERR(sup->rstc)) in sunplus_uart_probe()
616 return dev_err_probe(&pdev->dev, PTR_ERR(sup->rstc), "rstc not found\n"); in sunplus_uart_probe()
618 port = &sup->port; in sunplus_uart_probe()
620 port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in sunplus_uart_probe()
621 if (IS_ERR(port->membase)) in sunplus_uart_probe()
622 return dev_err_probe(&pdev->dev, PTR_ERR(port->membase), "membase not found\n"); in sunplus_uart_probe()
628 port->mapbase = res->start; in sunplus_uart_probe()
629 port->uartclk = clk_get_rate(sup->clk); in sunplus_uart_probe()
630 port->line = pdev->id; in sunplus_uart_probe()
631 port->irq = irq; in sunplus_uart_probe()
632 port->dev = &pdev->dev; in sunplus_uart_probe()
633 port->iotype = UPIO_MEM; in sunplus_uart_probe()
634 port->ops = &sunplus_uart_ops; in sunplus_uart_probe()
635 port->flags = UPF_BOOT_AUTOCONF; in sunplus_uart_probe()
636 port->fifosize = 128; in sunplus_uart_probe()
638 ret = reset_control_deassert(sup->rstc); in sunplus_uart_probe()
642 ret = devm_add_action_or_reset(&pdev->dev, sunplus_uart_reset_control_assert, sup->rstc); in sunplus_uart_probe()
647 sunplus_console_ports[sup->port.line] = sup; in sunplus_uart_probe()
650 platform_set_drvdata(pdev, &sup->port); in sunplus_uart_probe()
652 ret = uart_add_one_port(&sunplus_uart_driver, &sup->port); in sunplus_uart_probe()
655 sunplus_console_ports[sup->port.line] = NULL; in sunplus_uart_probe()
665 uart_remove_one_port(&sunplus_uart_driver, &sup->port); in sunplus_uart_remove()
672 if (!uart_console(&sup->port)) in sunplus_uart_suspend()
673 uart_suspend_port(&sunplus_uart_driver, &sup->port); in sunplus_uart_suspend()
682 if (!uart_console(&sup->port)) in sunplus_uart_resume()
683 uart_resume_port(&sunplus_uart_driver, &sup->port); in sunplus_uart_resume()
693 { .compatible = "sunplus,sp7021-uart" },
737 ret = readl_poll_timeout_atomic(port->membase + SUP_UART_LSR, val, in sunplus_uart_putc()
742 writel(c, port->membase + SUP_UART_DATA); in sunplus_uart_putc()
747 struct earlycon_device *dev = con->data; in sunplus_uart_early_write()
749 uart_console_write(&dev->port, s, n, sunplus_uart_putc); in sunplus_uart_early_write()
755 if (!(dev->port.membase || dev->port.iobase)) in sunplus_uart_early_setup()
756 return -ENODEV; in sunplus_uart_early_setup()
758 dev->con->write = sunplus_uart_early_write; in sunplus_uart_early_setup()
762 OF_EARLYCON_DECLARE(sunplus_uart, "sunplus,sp7021-uart", sunplus_uart_early_setup);