Lines Matching +full:tpl +full:- +full:support
1 // SPDX-License-Identifier: GPL-2.0-or-later
14 * Note: Although this driver assumes a 16550A-like UART implementation,
89 int index, ret = -EBUSY; in sdio_uart_add_port()
91 mutex_init(&port->func_lock); in sdio_uart_add_port()
92 spin_lock_init(&port->write_lock); in sdio_uart_add_port()
93 if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) in sdio_uart_add_port()
94 return -ENOMEM; in sdio_uart_add_port()
99 port->index = index; in sdio_uart_add_port()
120 tty_port_get(&port->port); in sdio_uart_port_get()
128 tty_port_put(&port->port); in sdio_uart_port_put()
136 sdio_uart_table[port->index] = NULL; in sdio_uart_port_remove()
146 mutex_lock(&port->port.mutex); in sdio_uart_port_remove()
147 mutex_lock(&port->func_lock); in sdio_uart_port_remove()
148 func = port->func; in sdio_uart_port_remove()
150 port->func = NULL; in sdio_uart_port_remove()
151 mutex_unlock(&port->func_lock); in sdio_uart_port_remove()
153 tty_port_tty_hangup(&port->port, false); in sdio_uart_port_remove()
154 mutex_unlock(&port->port.mutex); in sdio_uart_port_remove()
164 mutex_lock(&port->func_lock); in sdio_uart_claim_func()
165 if (unlikely(!port->func)) { in sdio_uart_claim_func()
166 mutex_unlock(&port->func_lock); in sdio_uart_claim_func()
167 return -ENODEV; in sdio_uart_claim_func()
169 if (likely(port->in_sdio_uart_irq != current)) in sdio_uart_claim_func()
170 sdio_claim_host(port->func); in sdio_uart_claim_func()
171 mutex_unlock(&port->func_lock); in sdio_uart_claim_func()
177 if (likely(port->in_sdio_uart_irq != current)) in sdio_uart_release_func()
178 sdio_release_host(port->func); in sdio_uart_release_func()
183 return sdio_readb(port->func, port->regs_offset + offset, NULL); in sdio_in()
188 sdio_writeb(port->func, value, port->regs_offset + offset, NULL); in sdio_out()
236 old = port->mctrl; in sdio_uart_update_mctrl()
237 port->mctrl = (old & ~clear) | set; in sdio_uart_update_mctrl()
238 if (old != port->mctrl) in sdio_uart_update_mctrl()
239 sdio_uart_write_mctrl(port, port->mctrl); in sdio_uart_update_mctrl()
252 cval = UART_LCR_WLEN(tty_get_char_size(termios->c_cflag)); in sdio_uart_change_speed()
254 if (termios->c_cflag & CSTOPB) in sdio_uart_change_speed()
256 if (termios->c_cflag & PARENB) in sdio_uart_change_speed()
258 if (!(termios->c_cflag & PARODD)) in sdio_uart_change_speed()
265 if (baud <= port->uartclk) in sdio_uart_change_speed()
271 termios->c_cflag &= ~CBAUD; in sdio_uart_change_speed()
273 termios->c_cflag |= old->c_cflag & CBAUD; in sdio_uart_change_speed()
276 termios->c_cflag |= B9600; in sdio_uart_change_speed()
278 quot = (2 * port->uartclk + baud) / (2 * baud); in sdio_uart_change_speed()
285 port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; in sdio_uart_change_speed()
286 if (termios->c_iflag & INPCK) in sdio_uart_change_speed()
287 port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; in sdio_uart_change_speed()
288 if (termios->c_iflag & (BRKINT | PARMRK)) in sdio_uart_change_speed()
289 port->read_status_mask |= UART_LSR_BI; in sdio_uart_change_speed()
294 port->ignore_status_mask = 0; in sdio_uart_change_speed()
295 if (termios->c_iflag & IGNPAR) in sdio_uart_change_speed()
296 port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; in sdio_uart_change_speed()
297 if (termios->c_iflag & IGNBRK) { in sdio_uart_change_speed()
298 port->ignore_status_mask |= UART_LSR_BI; in sdio_uart_change_speed()
301 * ignore overruns too (for real raw support). in sdio_uart_change_speed()
303 if (termios->c_iflag & IGNPAR) in sdio_uart_change_speed()
304 port->ignore_status_mask |= UART_LSR_OE; in sdio_uart_change_speed()
310 if ((termios->c_cflag & CREAD) == 0) in sdio_uart_change_speed()
311 port->ignore_status_mask |= UART_LSR_DR; in sdio_uart_change_speed()
316 port->ier &= ~UART_IER_MSI; in sdio_uart_change_speed()
317 if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL)) in sdio_uart_change_speed()
318 port->ier |= UART_IER_MSI; in sdio_uart_change_speed()
320 port->lcr = cval; in sdio_uart_change_speed()
322 sdio_out(port, UART_IER, port->ier); in sdio_uart_change_speed()
329 sdio_uart_write_mctrl(port, port->mctrl); in sdio_uart_change_speed()
334 if (!(port->ier & UART_IER_THRI)) { in sdio_uart_start_tx()
335 port->ier |= UART_IER_THRI; in sdio_uart_start_tx()
336 sdio_out(port, UART_IER, port->ier); in sdio_uart_start_tx()
342 if (port->ier & UART_IER_THRI) { in sdio_uart_stop_tx()
343 port->ier &= ~UART_IER_THRI; in sdio_uart_stop_tx()
344 sdio_out(port, UART_IER, port->ier); in sdio_uart_stop_tx()
350 port->ier &= ~UART_IER_RLSI; in sdio_uart_stop_rx()
351 port->read_status_mask &= ~UART_LSR_DR; in sdio_uart_stop_rx()
352 sdio_out(port, UART_IER, port->ier); in sdio_uart_stop_rx()
362 port->icount.rx++; in sdio_uart_receive_chars()
371 port->icount.brk++; in sdio_uart_receive_chars()
373 port->icount.parity++; in sdio_uart_receive_chars()
375 port->icount.frame++; in sdio_uart_receive_chars()
377 port->icount.overrun++; in sdio_uart_receive_chars()
382 *status &= port->read_status_mask; in sdio_uart_receive_chars()
391 if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) in sdio_uart_receive_chars()
392 tty_insert_flip_char(&port->port, ch, flag); in sdio_uart_receive_chars()
398 if (*status & ~port->ignore_status_mask & UART_LSR_OE) in sdio_uart_receive_chars()
399 tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); in sdio_uart_receive_chars()
402 } while ((*status & UART_LSR_DR) && (max_count-- > 0)); in sdio_uart_receive_chars()
404 tty_flip_buffer_push(&port->port); in sdio_uart_receive_chars()
409 struct kfifo *xmit = &port->xmit_fifo; in sdio_uart_transmit_chars()
415 if (port->x_char) { in sdio_uart_transmit_chars()
416 sdio_out(port, UART_TX, port->x_char); in sdio_uart_transmit_chars()
417 port->icount.tx++; in sdio_uart_transmit_chars()
418 port->x_char = 0; in sdio_uart_transmit_chars()
422 tty = tty_port_tty_get(&port->port); in sdio_uart_transmit_chars()
425 tty->flow.stopped || tty->hw_stopped) { in sdio_uart_transmit_chars()
431 len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock); in sdio_uart_transmit_chars()
434 port->icount.tx++; in sdio_uart_transmit_chars()
457 port->icount.rng++; in sdio_uart_check_modem_status()
459 port->icount.dsr++; in sdio_uart_check_modem_status()
461 port->icount.dcd++; in sdio_uart_check_modem_status()
462 /* DCD raise - wake for open */ in sdio_uart_check_modem_status()
464 wake_up_interruptible(&port->port.open_wait); in sdio_uart_check_modem_status()
466 /* DCD drop - hang up if tty attached */ in sdio_uart_check_modem_status()
467 tty_port_tty_hangup(&port->port, false); in sdio_uart_check_modem_status()
471 port->icount.cts++; in sdio_uart_check_modem_status()
472 tty = tty_port_tty_get(&port->port); in sdio_uart_check_modem_status()
475 if (tty->hw_stopped) { in sdio_uart_check_modem_status()
477 tty->hw_stopped = false; in sdio_uart_check_modem_status()
483 tty->hw_stopped = true; in sdio_uart_check_modem_status()
508 if (unlikely(port->in_sdio_uart_irq == current)) in sdio_uart_irq()
515 port->in_sdio_uart_irq = current; in sdio_uart_irq()
522 port->in_sdio_uart_irq = NULL; in sdio_uart_irq()
539 * uart_dtr_rts - port helper to set uart signals
562 * sdio_uart_activate - start up hardware
583 * Set the TTY IO error marker - we will only clear this in sdio_uart_activate()
586 set_bit(TTY_IO_ERROR, &tty->flags); in sdio_uart_activate()
588 kfifo_reset(&port->xmit_fifo); in sdio_uart_activate()
593 ret = sdio_enable_func(port->func); in sdio_uart_activate()
596 ret = sdio_claim_irq(port->func, sdio_uart_irq); in sdio_uart_activate()
622 port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE; in sdio_uart_activate()
623 port->mctrl = TIOCM_OUT2; in sdio_uart_activate()
625 sdio_uart_change_speed(port, &tty->termios, NULL); in sdio_uart_activate()
632 tty->hw_stopped = true; in sdio_uart_activate()
634 clear_bit(TTY_IO_ERROR, &tty->flags); in sdio_uart_activate()
637 sdio_uart_irq(port->func); in sdio_uart_activate()
643 sdio_disable_func(port->func); in sdio_uart_activate()
650 * sdio_uart_shutdown - stop hardware
672 sdio_release_irq(port->func); in sdio_uart_shutdown()
673 port->ier = 0; in sdio_uart_shutdown()
679 port->lcr &= ~UART_LCR_SBC; in sdio_uart_shutdown()
680 sdio_out(port, UART_LCR, port->lcr); in sdio_uart_shutdown()
686 sdio_disable_func(port->func); in sdio_uart_shutdown()
695 kfifo_free(&port->xmit_fifo); in sdio_uart_port_destroy()
700 * sdio_uart_install - install method
710 int idx = tty->index; in sdio_uart_install()
716 tty->driver_data = port; in sdio_uart_install()
723 * sdio_uart_cleanup - called on the last tty kref drop
727 * We cannot destroy the tty->driver_data port kref until this point
732 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_cleanup()
733 tty->driver_data = NULL; /* Bug trap */ in sdio_uart_cleanup()
743 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_open()
744 return tty_port_open(&port->port, tty, filp); in sdio_uart_open()
749 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_close()
750 tty_port_close(&port->port, tty, filp); in sdio_uart_close()
755 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_hangup()
756 tty_port_hangup(&port->port); in sdio_uart_hangup()
762 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_write()
765 if (!port->func) in sdio_uart_write()
766 return -ENODEV; in sdio_uart_write()
768 ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock); in sdio_uart_write()
769 if (!(port->ier & UART_IER_THRI)) { in sdio_uart_write()
773 sdio_uart_irq(port->func); in sdio_uart_write()
784 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_write_room()
785 return FIFO_SIZE - kfifo_len(&port->xmit_fifo); in sdio_uart_write_room()
790 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_chars_in_buffer()
791 return kfifo_len(&port->xmit_fifo); in sdio_uart_chars_in_buffer()
796 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_send_xchar()
798 port->x_char = ch; in sdio_uart_send_xchar()
799 if (ch && !(port->ier & UART_IER_THRI)) { in sdio_uart_send_xchar()
803 sdio_uart_irq(port->func); in sdio_uart_send_xchar()
810 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_throttle()
819 port->x_char = STOP_CHAR(tty); in sdio_uart_throttle()
826 sdio_uart_irq(port->func); in sdio_uart_throttle()
832 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_unthrottle()
841 if (port->x_char) { in sdio_uart_unthrottle()
842 port->x_char = 0; in sdio_uart_unthrottle()
844 port->x_char = START_CHAR(tty); in sdio_uart_unthrottle()
852 sdio_uart_irq(port->func); in sdio_uart_unthrottle()
859 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_set_termios()
860 unsigned int cflag = tty->termios.c_cflag; in sdio_uart_set_termios()
865 sdio_uart_change_speed(port, &tty->termios, old_termios); in sdio_uart_set_termios()
868 if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) in sdio_uart_set_termios()
872 if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { in sdio_uart_set_termios()
880 if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { in sdio_uart_set_termios()
881 tty->hw_stopped = false; in sdio_uart_set_termios()
886 if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { in sdio_uart_set_termios()
888 tty->hw_stopped = true; in sdio_uart_set_termios()
898 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_break_ctl()
905 if (break_state == -1) in sdio_uart_break_ctl()
906 port->lcr |= UART_LCR_SBC; in sdio_uart_break_ctl()
908 port->lcr &= ~UART_LCR_SBC; in sdio_uart_break_ctl()
909 sdio_out(port, UART_LCR, port->lcr); in sdio_uart_break_ctl()
917 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_tiocmget()
922 result = port->mctrl | sdio_uart_get_mctrl(port); in sdio_uart_tiocmget()
932 struct sdio_uart_port *port = tty->driver_data; in sdio_uart_tiocmset()
956 port->icount.tx, port->icount.rx); in sdio_uart_proc_show()
957 if (port->icount.frame) in sdio_uart_proc_show()
959 port->icount.frame); in sdio_uart_proc_show()
960 if (port->icount.parity) in sdio_uart_proc_show()
962 port->icount.parity); in sdio_uart_proc_show()
963 if (port->icount.brk) in sdio_uart_proc_show()
965 port->icount.brk); in sdio_uart_proc_show()
966 if (port->icount.overrun) in sdio_uart_proc_show()
968 port->icount.overrun); in sdio_uart_proc_show()
969 if (port->icount.cts) in sdio_uart_proc_show()
971 port->icount.cts); in sdio_uart_proc_show()
972 if (port->icount.dsr) in sdio_uart_proc_show()
974 port->icount.dsr); in sdio_uart_proc_show()
975 if (port->icount.rng) in sdio_uart_proc_show()
977 port->icount.rng); in sdio_uart_proc_show()
978 if (port->icount.dcd) in sdio_uart_proc_show()
980 port->icount.dcd); in sdio_uart_proc_show()
1026 return -ENOMEM; in sdio_uart_probe()
1028 if (func->class == SDIO_CLASS_UART) { in sdio_uart_probe()
1032 return -ENOSYS; in sdio_uart_probe()
1033 } else if (func->class == SDIO_CLASS_GPS) { in sdio_uart_probe()
1038 struct sdio_func_tuple *tpl; in sdio_uart_probe() local
1039 for (tpl = func->tuples; tpl; tpl = tpl->next) { in sdio_uart_probe()
1040 if (tpl->code != 0x91) in sdio_uart_probe()
1042 if (tpl->size < 10) in sdio_uart_probe()
1044 if (tpl->data[1] == 0) /* SUBTPL_SIOREG */ in sdio_uart_probe()
1047 if (!tpl) { in sdio_uart_probe()
1051 return -EINVAL; in sdio_uart_probe()
1054 sdio_func_id(func), tpl->data[2], tpl->data[3]); in sdio_uart_probe()
1055 port->regs_offset = (tpl->data[4] << 0) | in sdio_uart_probe()
1056 (tpl->data[5] << 8) | in sdio_uart_probe()
1057 (tpl->data[6] << 16); in sdio_uart_probe()
1059 sdio_func_id(func), port->regs_offset); in sdio_uart_probe()
1060 port->uartclk = tpl->data[7] * 115200; in sdio_uart_probe()
1061 if (port->uartclk == 0) in sdio_uart_probe()
1062 port->uartclk = 115200; in sdio_uart_probe()
1063 pr_debug("%s: clk %d baudcode %u 4800-div %u\n", in sdio_uart_probe()
1064 sdio_func_id(func), port->uartclk, in sdio_uart_probe()
1065 tpl->data[7], tpl->data[8] | (tpl->data[9] << 8)); in sdio_uart_probe()
1068 return -EINVAL; in sdio_uart_probe()
1071 port->func = func; in sdio_uart_probe()
1073 tty_port_init(&port->port); in sdio_uart_probe()
1074 port->port.ops = &sdio_uart_port_ops; in sdio_uart_probe()
1081 dev = tty_port_register_device(&port->port, in sdio_uart_probe()
1082 sdio_uart_tty_driver, port->index, &func->dev); in sdio_uart_probe()
1096 tty_unregister_device(sdio_uart_tty_driver, port->index); in sdio_uart_remove()
1125 tty_drv->driver_name = "sdio_uart"; in sdio_uart_init()
1126 tty_drv->name = "ttySDIO"; in sdio_uart_init()
1127 tty_drv->major = 0; /* dynamically allocated */ in sdio_uart_init()
1128 tty_drv->minor_start = 0; in sdio_uart_init()
1129 tty_drv->type = TTY_DRIVER_TYPE_SERIAL; in sdio_uart_init()
1130 tty_drv->subtype = SERIAL_TYPE_NORMAL; in sdio_uart_init()
1131 tty_drv->init_termios = tty_std_termios; in sdio_uart_init()
1132 tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL; in sdio_uart_init()
1133 tty_drv->init_termios.c_ispeed = 4800; in sdio_uart_init()
1134 tty_drv->init_termios.c_ospeed = 4800; in sdio_uart_init()