Lines Matching full:ssp
218 * @ssp: pointer to a struct sifive_serial_port record
221 * IP block base, given a pointer @ssp to a struct sifive_serial_port record.
225 static void __ssp_writel(u32 v, u16 offs, struct sifive_serial_port *ssp) in __ssp_writel() argument
227 __ssp_early_writel(v, offs, &ssp->port); in __ssp_writel()
232 * @ssp: pointer to a struct sifive_serial_port record
236 * IP block base, given a pointer @ssp to a struct sifive_serial_port record.
242 static u32 __ssp_readl(struct sifive_serial_port *ssp, u16 offs) in __ssp_readl() argument
244 return __ssp_early_readl(&ssp->port, offs); in __ssp_readl()
249 * @ssp: pointer to a struct sifive_serial_port
258 static int sifive_serial_is_txfifo_full(struct sifive_serial_port *ssp) in sifive_serial_is_txfifo_full() argument
260 return __ssp_readl(ssp, SIFIVE_SERIAL_TXDATA_OFFS) & in sifive_serial_is_txfifo_full()
266 * @ssp: pointer to a struct sifive_serial_port
269 * Enqueue a byte @ch onto the transmit FIFO, given a pointer @ssp to the
275 static void __ssp_transmit_char(struct sifive_serial_port *ssp, int ch) in __ssp_transmit_char() argument
277 __ssp_writel(ch, SIFIVE_SERIAL_TXDATA_OFFS, ssp); in __ssp_transmit_char()
282 * @ssp: pointer to a struct sifive_serial_port
287 * Context: Any context. Expects @ssp->port.lock to be held by caller.
289 static void __ssp_transmit_chars(struct sifive_serial_port *ssp) in __ssp_transmit_chars() argument
291 struct circ_buf *xmit = &ssp->port.state->xmit; in __ssp_transmit_chars()
294 if (ssp->port.x_char) { in __ssp_transmit_chars()
295 __ssp_transmit_char(ssp, ssp->port.x_char); in __ssp_transmit_chars()
296 ssp->port.icount.tx++; in __ssp_transmit_chars()
297 ssp->port.x_char = 0; in __ssp_transmit_chars()
300 if (uart_circ_empty(xmit) || uart_tx_stopped(&ssp->port)) { in __ssp_transmit_chars()
301 sifive_serial_stop_tx(&ssp->port); in __ssp_transmit_chars()
306 __ssp_transmit_char(ssp, xmit->buf[xmit->tail]); in __ssp_transmit_chars()
308 ssp->port.icount.tx++; in __ssp_transmit_chars()
314 uart_write_wakeup(&ssp->port); in __ssp_transmit_chars()
317 sifive_serial_stop_tx(&ssp->port); in __ssp_transmit_chars()
322 * @ssp: pointer to a struct sifive_serial_port
325 * on the SiFive UART referred to by @ssp.
327 static void __ssp_enable_txwm(struct sifive_serial_port *ssp) in __ssp_enable_txwm() argument
329 if (ssp->ier & SIFIVE_SERIAL_IE_TXWM_MASK) in __ssp_enable_txwm()
332 ssp->ier |= SIFIVE_SERIAL_IE_TXWM_MASK; in __ssp_enable_txwm()
333 __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp); in __ssp_enable_txwm()
338 * @ssp: pointer to a struct sifive_serial_port
341 * on the SiFive UART referred to by @ssp.
343 static void __ssp_enable_rxwm(struct sifive_serial_port *ssp) in __ssp_enable_rxwm() argument
345 if (ssp->ier & SIFIVE_SERIAL_IE_RXWM_MASK) in __ssp_enable_rxwm()
348 ssp->ier |= SIFIVE_SERIAL_IE_RXWM_MASK; in __ssp_enable_rxwm()
349 __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp); in __ssp_enable_rxwm()
354 * @ssp: pointer to a struct sifive_serial_port
357 * on the UART referred to by @ssp.
359 static void __ssp_disable_txwm(struct sifive_serial_port *ssp) in __ssp_disable_txwm() argument
361 if (!(ssp->ier & SIFIVE_SERIAL_IE_TXWM_MASK)) in __ssp_disable_txwm()
364 ssp->ier &= ~SIFIVE_SERIAL_IE_TXWM_MASK; in __ssp_disable_txwm()
365 __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp); in __ssp_disable_txwm()
370 * @ssp: pointer to a struct sifive_serial_port
373 * on the UART referred to by @ssp.
375 static void __ssp_disable_rxwm(struct sifive_serial_port *ssp) in __ssp_disable_rxwm() argument
377 if (!(ssp->ier & SIFIVE_SERIAL_IE_RXWM_MASK)) in __ssp_disable_rxwm()
380 ssp->ier &= ~SIFIVE_SERIAL_IE_RXWM_MASK; in __ssp_disable_rxwm()
381 __ssp_writel(ssp->ier, SIFIVE_SERIAL_IE_OFFS, ssp); in __ssp_disable_rxwm()
386 * @ssp: pointer to a struct sifive_serial_port
390 * @ssp, and to return it. Also returns the RX FIFO empty bit in
396 static char __ssp_receive_char(struct sifive_serial_port *ssp, char *is_empty) in __ssp_receive_char() argument
401 v = __ssp_readl(ssp, SIFIVE_SERIAL_RXDATA_OFFS); in __ssp_receive_char()
417 * @ssp: pointer to a struct sifive_serial_port
420 * to by @ssp and pass them up to the Linux serial layer.
422 * Context: Expects ssp->port.lock to be held by caller.
424 static void __ssp_receive_chars(struct sifive_serial_port *ssp) in __ssp_receive_chars() argument
431 ch = __ssp_receive_char(ssp, &is_empty); in __ssp_receive_chars()
435 ssp->port.icount.rx++; in __ssp_receive_chars()
436 uart_insert_char(&ssp->port, 0, 0, ch, TTY_NORMAL); in __ssp_receive_chars()
439 tty_flip_buffer_push(&ssp->port.state->port); in __ssp_receive_chars()
444 * @ssp: pointer to a struct sifive_serial_port
447 * and target line rate referred to by @ssp and write it into the
450 static void __ssp_update_div(struct sifive_serial_port *ssp) in __ssp_update_div() argument
454 div = DIV_ROUND_UP(ssp->port.uartclk, ssp->baud_rate) - 1; in __ssp_update_div()
456 __ssp_writel(div, SIFIVE_SERIAL_DIV_OFFS, ssp); in __ssp_update_div()
461 * @ssp: pointer to a struct sifive_serial_port
465 * SiFive UART described by @ssp and program it into the UART. There may
469 static void __ssp_update_baud_rate(struct sifive_serial_port *ssp, in __ssp_update_baud_rate() argument
472 if (ssp->baud_rate == rate) in __ssp_update_baud_rate()
475 ssp->baud_rate = rate; in __ssp_update_baud_rate()
476 __ssp_update_div(ssp); in __ssp_update_baud_rate()
481 * @ssp: pointer to a struct sifive_serial_port
484 * Program the SiFive UART referred to by @ssp to use @nstop stop bits.
486 static void __ssp_set_stop_bits(struct sifive_serial_port *ssp, char nstop) in __ssp_set_stop_bits() argument
495 v = __ssp_readl(ssp, SIFIVE_SERIAL_TXCTRL_OFFS); in __ssp_set_stop_bits()
498 __ssp_writel(v, SIFIVE_SERIAL_TXCTRL_OFFS, ssp); in __ssp_set_stop_bits()
503 * @ssp: pointer to a struct sifive_serial_port
505 * Delay while the UART TX FIFO referred to by @ssp is marked as full.
509 static void __maybe_unused __ssp_wait_for_xmitr(struct sifive_serial_port *ssp) in __ssp_wait_for_xmitr() argument
511 while (sifive_serial_is_txfifo_full(ssp)) in __ssp_wait_for_xmitr()
521 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_stop_tx() local
523 __ssp_disable_txwm(ssp); in sifive_serial_stop_tx()
528 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_stop_rx() local
530 __ssp_disable_rxwm(ssp); in sifive_serial_stop_rx()
535 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_start_tx() local
537 __ssp_enable_txwm(ssp); in sifive_serial_start_tx()
542 struct sifive_serial_port *ssp = dev_id; in sifive_serial_irq() local
545 spin_lock(&ssp->port.lock); in sifive_serial_irq()
547 ip = __ssp_readl(ssp, SIFIVE_SERIAL_IP_OFFS); in sifive_serial_irq()
549 spin_unlock(&ssp->port.lock); in sifive_serial_irq()
554 __ssp_receive_chars(ssp); in sifive_serial_irq()
556 __ssp_transmit_chars(ssp); in sifive_serial_irq()
558 spin_unlock(&ssp->port.lock); in sifive_serial_irq()
585 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_startup() local
587 __ssp_enable_rxwm(ssp); in sifive_serial_startup()
594 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_shutdown() local
596 __ssp_disable_rxwm(ssp); in sifive_serial_shutdown()
597 __ssp_disable_txwm(ssp); in sifive_serial_shutdown()
617 struct sifive_serial_port *ssp = notifier_to_sifive_serial_port(nb); in sifive_serial_clk_notifier() local
626 __ssp_wait_for_xmitr(ssp); in sifive_serial_clk_notifier()
636 udelay(DIV_ROUND_UP(12 * 1000 * 1000, ssp->baud_rate)); in sifive_serial_clk_notifier()
639 if (event == POST_RATE_CHANGE && ssp->port.uartclk != cnd->new_rate) { in sifive_serial_clk_notifier()
640 ssp->port.uartclk = cnd->new_rate; in sifive_serial_clk_notifier()
641 __ssp_update_div(ssp); in sifive_serial_clk_notifier()
651 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_set_termios() local
658 dev_err_once(ssp->port.dev, "only 8-bit words supported\n"); in sifive_serial_set_termios()
663 dev_err_once(ssp->port.dev, "parity checking not supported\n"); in sifive_serial_set_termios()
665 dev_err_once(ssp->port.dev, "BREAK detection not supported\n"); in sifive_serial_set_termios()
670 __ssp_set_stop_bits(ssp, nstop); in sifive_serial_set_termios()
674 ssp->port.uartclk / 16); in sifive_serial_set_termios()
675 __ssp_update_baud_rate(ssp, rate); in sifive_serial_set_termios()
677 spin_lock_irqsave(&ssp->port.lock, flags); in sifive_serial_set_termios()
682 ssp->port.read_status_mask = 0; in sifive_serial_set_termios()
685 v = __ssp_readl(ssp, SIFIVE_SERIAL_RXCTRL_OFFS); in sifive_serial_set_termios()
692 __ssp_writel(v, SIFIVE_SERIAL_RXCTRL_OFFS, ssp); in sifive_serial_set_termios()
694 spin_unlock_irqrestore(&ssp->port.lock, flags); in sifive_serial_set_termios()
708 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_config_port() local
710 ssp->port.type = PORT_SIFIVE_V0; in sifive_serial_config_port()
727 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_poll_get_char() local
730 ch = __ssp_receive_char(ssp, &is_empty); in sifive_serial_poll_get_char()
740 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_poll_put_char() local
742 __ssp_wait_for_xmitr(ssp); in sifive_serial_poll_put_char()
743 __ssp_transmit_char(ssp, c); in sifive_serial_poll_put_char()
798 struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); in sifive_serial_console_putchar() local
800 __ssp_wait_for_xmitr(ssp); in sifive_serial_console_putchar()
801 __ssp_transmit_char(ssp, ch); in sifive_serial_console_putchar()
807 struct sifive_serial_port *ssp = sifive_serial_console_ports[co->index]; in sifive_serial_console_write() local
812 if (!ssp) in sifive_serial_console_write()
816 if (ssp->port.sysrq) in sifive_serial_console_write()
819 locked = spin_trylock(&ssp->port.lock); in sifive_serial_console_write()
821 spin_lock(&ssp->port.lock); in sifive_serial_console_write()
823 ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS); in sifive_serial_console_write()
824 __ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp); in sifive_serial_console_write()
826 uart_console_write(&ssp->port, s, count, sifive_serial_console_putchar); in sifive_serial_console_write()
828 __ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp); in sifive_serial_console_write()
831 spin_unlock(&ssp->port.lock); in sifive_serial_console_write()
837 struct sifive_serial_port *ssp; in sifive_serial_console_setup() local
846 ssp = sifive_serial_console_ports[co->index]; in sifive_serial_console_setup()
847 if (!ssp) in sifive_serial_console_setup()
853 return uart_set_options(&ssp->port, co, baud, parity, bits, flow); in sifive_serial_console_setup()
876 static void __ssp_add_console_port(struct sifive_serial_port *ssp) in __ssp_add_console_port() argument
878 sifive_serial_console_ports[ssp->port.line] = ssp; in __ssp_add_console_port()
881 static void __ssp_remove_console_port(struct sifive_serial_port *ssp) in __ssp_remove_console_port() argument
883 sifive_serial_console_ports[ssp->port.line] = NULL; in __ssp_remove_console_port()
892 static void __ssp_add_console_port(struct sifive_serial_port *ssp) in __ssp_add_console_port() argument
894 static void __ssp_remove_console_port(struct sifive_serial_port *ssp) in __ssp_remove_console_port() argument
931 struct sifive_serial_port *ssp; in sifive_serial_probe() local
967 ssp = devm_kzalloc(&pdev->dev, sizeof(*ssp), GFP_KERNEL); in sifive_serial_probe()
968 if (!ssp) in sifive_serial_probe()
971 ssp->port.dev = &pdev->dev; in sifive_serial_probe()
972 ssp->port.type = PORT_SIFIVE_V0; in sifive_serial_probe()
973 ssp->port.iotype = UPIO_MEM; in sifive_serial_probe()
974 ssp->port.irq = irq; in sifive_serial_probe()
975 ssp->port.fifosize = SIFIVE_TX_FIFO_DEPTH; in sifive_serial_probe()
976 ssp->port.ops = &sifive_serial_uops; in sifive_serial_probe()
977 ssp->port.line = id; in sifive_serial_probe()
978 ssp->port.mapbase = mem->start; in sifive_serial_probe()
979 ssp->port.membase = base; in sifive_serial_probe()
980 ssp->dev = &pdev->dev; in sifive_serial_probe()
981 ssp->clk = clk; in sifive_serial_probe()
982 ssp->clk_notifier.notifier_call = sifive_serial_clk_notifier; in sifive_serial_probe()
984 r = clk_notifier_register(ssp->clk, &ssp->clk_notifier); in sifive_serial_probe()
992 ssp->port.uartclk = clk_get_rate(ssp->clk); in sifive_serial_probe()
993 ssp->baud_rate = SIFIVE_DEFAULT_BAUD_RATE; in sifive_serial_probe()
994 __ssp_update_div(ssp); in sifive_serial_probe()
996 platform_set_drvdata(pdev, ssp); in sifive_serial_probe()
1001 SIFIVE_SERIAL_TXCTRL_OFFS, ssp); in sifive_serial_probe()
1006 SIFIVE_SERIAL_RXCTRL_OFFS, ssp); in sifive_serial_probe()
1008 r = request_irq(ssp->port.irq, sifive_serial_irq, ssp->port.irqflags, in sifive_serial_probe()
1009 dev_name(&pdev->dev), ssp); in sifive_serial_probe()
1015 __ssp_add_console_port(ssp); in sifive_serial_probe()
1017 r = uart_add_one_port(&sifive_serial_uart_driver, &ssp->port); in sifive_serial_probe()
1026 __ssp_remove_console_port(ssp); in sifive_serial_probe()
1027 free_irq(ssp->port.irq, ssp); in sifive_serial_probe()
1029 clk_notifier_unregister(ssp->clk, &ssp->clk_notifier); in sifive_serial_probe()
1036 struct sifive_serial_port *ssp = platform_get_drvdata(dev); in sifive_serial_remove() local
1038 __ssp_remove_console_port(ssp); in sifive_serial_remove()
1039 uart_remove_one_port(&sifive_serial_uart_driver, &ssp->port); in sifive_serial_remove()
1040 free_irq(ssp->port.irq, ssp); in sifive_serial_remove()
1041 clk_notifier_unregister(ssp->clk, &ssp->clk_notifier); in sifive_serial_remove()