Lines Matching +full:mux +full:- +full:int +full:- +full:port

1 // SPDX-License-Identifier: GPL-2.0
3 * dz.c: Serial port driver for DECstations equipped
12 * [31-AUG-98] triemer
14 * removed base_addr code - moving address assignment to setup.c
16 * [13-NOV-98] triemer fixed code to receive characters
18 * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
19 * field from "current" - somewhere between 2.1.121 and 2.1.131
21 * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
24 * [07-SEP-99] Bugfixes
26 * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
71 struct dz_mux *mux; member
72 struct uart_port port; member
73 unsigned int cflag;
80 int initialised;
87 return container_of(uport, struct dz_port, port); in to_dport()
91 * ------------------------------------------------------------
96 * ------------------------------------------------------------
101 void __iomem *addr = dport->port.membase + offset; in dz_in()
108 void __iomem *addr = dport->port.membase + offset; in dz_out()
114 * ------------------------------------------------------------
118 * tty->flow.stopped. They enable or disable transmitter interrupts,
120 * ------------------------------------------------------------
126 u16 tmp, mask = 1 << dport->port.line; in dz_stop_tx()
136 u16 tmp, mask = 1 << dport->port.line; in dz_start_tx()
147 dport->cflag &= ~DZ_RXENAB; in dz_stop_rx()
148 dz_out(dport, DZ_LPR, dport->cflag); in dz_stop_rx()
152 * ------------------------------------------------------------
168 * ------------------------------------------------------------
172 * ------------------------------------------------------------
176 * ------------------------------------------------------------
178 static inline void dz_receive_chars(struct dz_mux *mux) in dz_receive_chars() argument
181 struct dz_port *dport = &mux->dport[0]; in dz_receive_chars()
183 int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; in dz_receive_chars()
186 int i; in dz_receive_chars()
189 dport = &mux->dport[LINE(status)]; in dz_receive_chars()
190 uport = &dport->port; in dz_receive_chars()
195 icount = &uport->icount; in dz_receive_chars()
196 icount->rx++; in dz_receive_chars()
208 (ffs(DZ_FERR) - ffs(DZ_BREAK)); in dz_receive_chars()
214 icount->brk++; in dz_receive_chars()
218 icount->frame++; in dz_receive_chars()
220 icount->parity++; in dz_receive_chars()
222 icount->overrun++; in dz_receive_chars()
224 status &= uport->read_status_mask; in dz_receive_chars()
242 tty_flip_buffer_push(&mux->dport[i].port.state->port); in dz_receive_chars()
246 * ------------------------------------------------------------
250 * ------------------------------------------------------------
252 static inline void dz_transmit_chars(struct dz_mux *mux) in dz_transmit_chars() argument
254 struct dz_port *dport = &mux->dport[0]; in dz_transmit_chars()
260 dport = &mux->dport[LINE(status)]; in dz_transmit_chars()
261 tport = &dport->port.state->port; in dz_transmit_chars()
263 if (dport->port.x_char) { /* XON/XOFF chars */ in dz_transmit_chars()
264 dz_out(dport, DZ_TDR, dport->port.x_char); in dz_transmit_chars()
265 dport->port.icount.tx++; in dz_transmit_chars()
266 dport->port.x_char = 0; in dz_transmit_chars()
270 if (uart_tx_stopped(&dport->port) || in dz_transmit_chars()
271 !uart_fifo_get(&dport->port, &tmp)) { in dz_transmit_chars()
272 uart_port_lock(&dport->port); in dz_transmit_chars()
273 dz_stop_tx(&dport->port); in dz_transmit_chars()
274 uart_port_unlock(&dport->port); in dz_transmit_chars()
280 * so we go one char at a time) :-< in dz_transmit_chars()
284 if (kfifo_len(&tport->xmit_fifo) < DZ_WAKEUP_CHARS) in dz_transmit_chars()
285 uart_write_wakeup(&dport->port); in dz_transmit_chars()
288 if (kfifo_is_empty(&tport->xmit_fifo)) { in dz_transmit_chars()
289 uart_port_lock(&dport->port); in dz_transmit_chars()
290 dz_stop_tx(&dport->port); in dz_transmit_chars()
291 uart_port_unlock(&dport->port); in dz_transmit_chars()
296 * ------------------------------------------------------------
301 * ------------------------------------------------------------
308 * 2. Handle the 3100/5000 as appropriate. --macro in check_modem_status()
313 if (dport->port.line != DZ_MODEM) in check_modem_status()
320 dport->port.icount.dsr++; in check_modem_status()
324 * ------------------------------------------------------------
329 * ------------------------------------------------------------
331 static irqreturn_t dz_interrupt(int irq, void *dev_id) in dz_interrupt()
333 struct dz_mux *mux = dev_id; in dz_interrupt() local
334 struct dz_port *dport = &mux->dport[0]; in dz_interrupt()
341 dz_receive_chars(mux); in dz_interrupt()
344 dz_transmit_chars(mux); in dz_interrupt()
350 * -------------------------------------------------------------------
352 * -------------------------------------------------------------------
355 static unsigned int dz_get_mctrl(struct uart_port *uport) in dz_get_mctrl()
358 * FIXME: Handle the 3100/5000 as appropriate. --macro in dz_get_mctrl()
361 unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; in dz_get_mctrl()
363 if (dport->port.line == DZ_MODEM) { in dz_get_mctrl()
371 static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl) in dz_set_mctrl()
374 * FIXME: Handle the 3100/5000 as appropriate. --macro in dz_set_mctrl()
379 if (dport->port.line == DZ_MODEM) { in dz_set_mctrl()
390 * -------------------------------------------------------------------
394 * -------------------------------------------------------------------
396 static int dz_startup(struct uart_port *uport) in dz_startup()
399 struct dz_mux *mux = dport->mux; in dz_startup() local
401 int irq_guard; in dz_startup()
402 int ret; in dz_startup()
405 irq_guard = atomic_add_return(1, &mux->irq_guard); in dz_startup()
409 ret = request_irq(dport->port.irq, dz_interrupt, in dz_startup()
410 IRQF_SHARED, "dz", mux); in dz_startup()
412 atomic_add(-1, &mux->irq_guard); in dz_startup()
413 printk(KERN_ERR "dz: Cannot get IRQ %d!\n", dport->port.irq); in dz_startup()
417 uart_port_lock_irqsave(&dport->port, &flags); in dz_startup()
424 uart_port_unlock_irqrestore(&dport->port, flags); in dz_startup()
430 * -------------------------------------------------------------------
433 * This routine will shutdown a serial port; interrupts are disabled, and
435 * -------------------------------------------------------------------
440 struct dz_mux *mux = dport->mux; in dz_shutdown() local
442 int irq_guard; in dz_shutdown()
445 uart_port_lock_irqsave(&dport->port, &flags); in dz_shutdown()
446 dz_stop_tx(&dport->port); in dz_shutdown()
447 uart_port_unlock_irqrestore(&dport->port, flags); in dz_shutdown()
449 irq_guard = atomic_add_return(-1, &mux->irq_guard); in dz_shutdown()
456 free_irq(dport->port.irq, mux); in dz_shutdown()
461 * -------------------------------------------------------------------
462 * dz_tx_empty() -- get the transmitter empty status
470 * -------------------------------------------------------------------
472 static unsigned int dz_tx_empty(struct uart_port *uport) in dz_tx_empty()
475 unsigned short tmp, mask = 1 << dport->port.line; in dz_tx_empty()
483 static void dz_break_ctl(struct uart_port *uport, int break_state) in dz_break_ctl()
487 * reuse the code for polled TX. --macro in dz_break_ctl()
491 unsigned short tmp, mask = 1 << dport->port.line; in dz_break_ctl()
503 static int dz_encode_baud_rate(unsigned int baud) in dz_encode_baud_rate()
537 return -1; in dz_encode_baud_rate()
544 struct dz_mux *mux = dport->mux; in dz_reset() local
546 if (mux->initialised) in dz_reset()
556 mux->initialised = 1; in dz_reset()
564 unsigned int cflag, baud; in dz_set_termios()
565 int bflag; in dz_set_termios()
567 cflag = dport->port.line; in dz_set_termios()
569 switch (termios->c_cflag & CSIZE) { in dz_set_termios()
584 if (termios->c_cflag & CSTOPB) in dz_set_termios()
586 if (termios->c_cflag & PARENB) in dz_set_termios()
588 if (termios->c_cflag & PARODD) in dz_set_termios()
607 if (termios->c_cflag & CREAD) in dz_set_termios()
610 uart_port_lock_irqsave(&dport->port, &flags); in dz_set_termios()
612 uart_update_timeout(uport, termios->c_cflag, baud); in dz_set_termios()
615 dport->cflag = cflag; in dz_set_termios()
618 dport->port.read_status_mask = DZ_OERR; in dz_set_termios()
619 if (termios->c_iflag & INPCK) in dz_set_termios()
620 dport->port.read_status_mask |= DZ_FERR | DZ_PERR; in dz_set_termios()
621 if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) in dz_set_termios()
622 dport->port.read_status_mask |= DZ_BREAK; in dz_set_termios()
625 uport->ignore_status_mask = 0; in dz_set_termios()
626 if ((termios->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) in dz_set_termios()
627 dport->port.ignore_status_mask |= DZ_OERR; in dz_set_termios()
628 if (termios->c_iflag & IGNPAR) in dz_set_termios()
629 dport->port.ignore_status_mask |= DZ_FERR | DZ_PERR; in dz_set_termios()
630 if (termios->c_iflag & IGNBRK) in dz_set_termios()
631 dport->port.ignore_status_mask |= DZ_BREAK; in dz_set_termios()
633 uart_port_unlock_irqrestore(&dport->port, flags); in dz_set_termios()
638 * Required solely so that the initial PROM-based console
641 static void dz_pm(struct uart_port *uport, unsigned int state, in dz_pm()
642 unsigned int oldstate) in dz_pm()
647 uart_port_lock_irqsave(&dport->port, &flags); in dz_pm()
649 dz_start_tx(&dport->port); in dz_pm()
651 dz_stop_tx(&dport->port); in dz_pm()
652 uart_port_unlock_irqrestore(&dport->port, flags); in dz_pm()
663 struct dz_mux *mux = to_dport(uport)->mux; in dz_release_port() local
664 int map_guard; in dz_release_port()
666 iounmap(uport->membase); in dz_release_port()
667 uport->membase = NULL; in dz_release_port()
669 map_guard = atomic_add_return(-1, &mux->map_guard); in dz_release_port()
671 release_mem_region(uport->mapbase, dec_kn_slot_size); in dz_release_port()
674 static int dz_map_port(struct uart_port *uport) in dz_map_port()
676 if (!uport->membase) in dz_map_port()
677 uport->membase = ioremap(uport->mapbase, in dz_map_port()
679 if (!uport->membase) { in dz_map_port()
681 return -ENOMEM; in dz_map_port()
686 static int dz_request_port(struct uart_port *uport) in dz_request_port()
688 struct dz_mux *mux = to_dport(uport)->mux; in dz_request_port() local
689 int map_guard; in dz_request_port()
690 int ret; in dz_request_port()
692 map_guard = atomic_add_return(1, &mux->map_guard); in dz_request_port()
694 if (!request_mem_region(uport->mapbase, dec_kn_slot_size, in dz_request_port()
696 atomic_add(-1, &mux->map_guard); in dz_request_port()
699 return -EBUSY; in dz_request_port()
704 map_guard = atomic_add_return(-1, &mux->map_guard); in dz_request_port()
706 release_mem_region(uport->mapbase, dec_kn_slot_size); in dz_request_port()
712 static void dz_config_port(struct uart_port *uport, int flags) in dz_config_port()
720 uport->type = PORT_DZ; in dz_config_port()
729 static int dz_verify_port(struct uart_port *uport, struct serial_struct *ser) in dz_verify_port()
731 int ret = 0; in dz_verify_port()
733 if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ) in dz_verify_port()
734 ret = -EINVAL; in dz_verify_port()
735 if (ser->irq != uport->irq) in dz_verify_port()
736 ret = -EINVAL; in dz_verify_port()
761 static int first = 1; in dz_init_ports()
763 int line; in dz_init_ports()
776 struct uart_port *uport = &dport->port; in dz_init_ports()
778 dport->mux = &dz_mux; in dz_init_ports()
780 uport->irq = dec_interrupt[DEC_IRQ_DZ11]; in dz_init_ports()
781 uport->fifosize = 1; in dz_init_ports()
782 uport->iotype = UPIO_MEM; in dz_init_ports()
783 uport->flags = UPF_BOOT_AUTOCONF; in dz_init_ports()
784 uport->ops = &dz_ops; in dz_init_ports()
785 uport->line = line; in dz_init_ports()
786 uport->mapbase = base; in dz_init_ports()
787 uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_DZ_CONSOLE); in dz_init_ports()
793 * -------------------------------------------------------------------
794 * dz_console_putchar() -- transmit a character
803 * restored. Welcome to the world of PDP-11!
804 * -------------------------------------------------------------------
811 int loops = 10000; in dz_console_putchar()
813 uart_port_lock_irqsave(&dport->port, &flags); in dz_console_putchar()
817 tcr |= 1 << dport->port.line; in dz_console_putchar()
821 uart_port_unlock_irqrestore(&dport->port, flags); in dz_console_putchar()
828 if (trdy == dport->port.line) in dz_console_putchar()
834 } while (--loops); in dz_console_putchar()
844 * -------------------------------------------------------------------
849 * -------------------------------------------------------------------
853 unsigned int count) in dz_console_print()
855 struct dz_port *dport = &dz_mux.dport[co->index]; in dz_console_print()
859 uart_console_write(&dport->port, str, count, dz_console_putchar); in dz_console_print()
862 static int __init dz_console_setup(struct console *co, char *options) in dz_console_setup()
864 struct dz_port *dport = &dz_mux.dport[co->index]; in dz_console_setup()
865 struct uart_port *uport = &dport->port; in dz_console_setup()
866 int baud = 9600; in dz_console_setup()
867 int bits = 8; in dz_console_setup()
868 int parity = 'n'; in dz_console_setup()
869 int flow = 'n'; in dz_console_setup()
870 int ret; in dz_console_setup()
876 spin_lock_init(&dport->port.lock); /* For dz_pm(). */ in dz_console_setup()
879 dz_pm(uport, 0, -1); in dz_console_setup()
884 return uart_set_options(&dport->port, co, baud, parity, bits, flow); in dz_console_setup()
894 .index = -1,
898 static int __init dz_serial_console_init(void) in dz_serial_console_init()
905 return -ENXIO; in dz_serial_console_init()
925 static int __init dz_init(void) in dz_init()
927 int ret, i; in dz_init()
930 return -ENXIO; in dz_init()
941 uart_add_one_port(&dz_reg, &dz_mux.dport[i].port); in dz_init()