Lines Matching +full:up +full:- +full:to

1 // SPDX-License-Identifier: GPL-2.0
6 * Copyright (C) 1998-1999 Pete Zaitcev (zaitcev@yahoo.com)
8 * This is mainly a variation of 8250.c, credits go to authors mentioned
12 * Fixed to use tty_get_baud_rate().
13 * Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
15 * Converted to new 2.5.x UART layer.
16 * David S. Miller (davem@davemloft.net), 2002-Jul-29
104 static unsigned int serial_in(struct uart_sunsu_port *up, int offset) in serial_in() argument
106 offset <<= up->port.regshift; in serial_in()
108 switch (up->port.iotype) { in serial_in()
110 outb(up->port.hub6 - 1 + offset, up->port.iobase); in serial_in()
111 return inb(up->port.iobase + 1); in serial_in()
114 return readb(up->port.membase + offset); in serial_in()
117 return inb(up->port.iobase + offset); in serial_in()
121 static void serial_out(struct uart_sunsu_port *up, int offset, int value) in serial_out() argument
126 * connected with a gate then go to SlavIO. When IRQ4 goes tristated in serial_out()
130 * This problem is similar to what Alpha people suffer, see in serial_out()
136 offset <<= up->port.regshift; in serial_out()
138 switch (up->port.iotype) { in serial_out()
140 outb(up->port.hub6 - 1 + offset, up->port.iobase); in serial_out()
141 outb(value, up->port.iobase + 1); in serial_out()
145 writeb(value, up->port.membase + offset); in serial_out()
149 outb(value, up->port.iobase + offset); in serial_out()
154 * We used to support using pause I/O for certain machines. We
159 #define serial_inp(up, offset) serial_in(up, offset) argument
160 #define serial_outp(up, offset, value) serial_out(up, offset, value) argument
166 static void serial_icr_write(struct uart_sunsu_port *up, int offset, int value) in serial_icr_write() argument
168 serial_out(up, UART_SCR, offset); in serial_icr_write()
169 serial_out(up, UART_ICR, value); in serial_icr_write()
173 static unsigned int serial_icr_read(struct uart_sunsu_port *up, int offset)
177 serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
178 serial_out(up, UART_SCR, offset);
179 value = serial_in(up, UART_ICR);
180 serial_icr_write(up, UART_ACR, up->acr);
188 * Attempts to turn on the RSA FIFO. Returns zero on failure.
191 static int __enable_rsa(struct uart_sunsu_port *up) in __enable_rsa() argument
196 mode = serial_inp(up, UART_RSA_MSR); in __enable_rsa()
200 serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); in __enable_rsa()
201 mode = serial_inp(up, UART_RSA_MSR); in __enable_rsa()
206 up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16; in __enable_rsa()
211 static void enable_rsa(struct uart_sunsu_port *up) in enable_rsa() argument
213 if (up->port.type == PORT_RSA) { in enable_rsa()
214 if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { in enable_rsa()
215 uart_port_lock_irq(&up->port); in enable_rsa()
216 __enable_rsa(up); in enable_rsa()
217 uart_port_unlock_irq(&up->port); in enable_rsa()
219 if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) in enable_rsa()
220 serial_outp(up, UART_RSA_FRR, 0); in enable_rsa()
225 * Attempts to turn off the RSA FIFO. Returns zero on failure.
227 * the caller is expected to preserve this behaviour by grabbing
230 static void disable_rsa(struct uart_sunsu_port *up) in disable_rsa() argument
235 if (up->port.type == PORT_RSA && in disable_rsa()
236 up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { in disable_rsa()
237 uart_port_lock_irq(&up->port); in disable_rsa()
239 mode = serial_inp(up, UART_RSA_MSR); in disable_rsa()
243 serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); in disable_rsa()
244 mode = serial_inp(up, UART_RSA_MSR); in disable_rsa()
249 up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; in disable_rsa()
250 uart_port_unlock_irq(&up->port); in disable_rsa()
257 if (p->ier & UART_IER_THRI) { in __stop_tx()
258 p->ier &= ~UART_IER_THRI; in __stop_tx()
259 serial_out(p, UART_IER, p->ier); in __stop_tx()
265 struct uart_sunsu_port *up = in sunsu_stop_tx() local
268 __stop_tx(up); in sunsu_stop_tx()
271 * We really want to stop the transmitter from sending. in sunsu_stop_tx()
273 if (up->port.type == PORT_16C950) { in sunsu_stop_tx()
274 up->acr |= UART_ACR_TXDIS; in sunsu_stop_tx()
275 serial_icr_write(up, UART_ACR, up->acr); in sunsu_stop_tx()
281 struct uart_sunsu_port *up = in sunsu_start_tx() local
284 if (!(up->ier & UART_IER_THRI)) { in sunsu_start_tx()
285 up->ier |= UART_IER_THRI; in sunsu_start_tx()
286 serial_out(up, UART_IER, up->ier); in sunsu_start_tx()
290 * Re-enable the transmitter if we disabled it. in sunsu_start_tx()
292 if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { in sunsu_start_tx()
293 up->acr &= ~UART_ACR_TXDIS; in sunsu_start_tx()
294 serial_icr_write(up, UART_ACR, up->acr); in sunsu_start_tx()
300 struct uart_sunsu_port *up = in sunsu_stop_rx() local
303 up->ier &= ~UART_IER_RLSI; in sunsu_stop_rx()
304 up->port.read_status_mask &= ~UART_LSR_DR; in sunsu_stop_rx()
305 serial_out(up, UART_IER, up->ier); in sunsu_stop_rx()
310 struct uart_sunsu_port *up = in sunsu_enable_ms() local
314 uart_port_lock_irqsave(&up->port, &flags); in sunsu_enable_ms()
315 up->ier |= UART_IER_MSI; in sunsu_enable_ms()
316 serial_out(up, UART_IER, up->ier); in sunsu_enable_ms()
317 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_enable_ms()
321 receive_chars(struct uart_sunsu_port *up, unsigned char *status) in receive_chars() argument
323 struct tty_port *port = &up->port.state->port; in receive_chars()
329 ch = serial_inp(up, UART_RX); in receive_chars()
331 up->port.icount.rx++; in receive_chars()
340 up->port.icount.brk++; in receive_chars()
341 if (up->port.cons != NULL && in receive_chars()
342 up->port.line == up->port.cons->index) in receive_chars()
350 if (uart_handle_break(&up->port)) in receive_chars()
353 up->port.icount.parity++; in receive_chars()
355 up->port.icount.frame++; in receive_chars()
357 up->port.icount.overrun++; in receive_chars()
362 *status &= up->port.read_status_mask; in receive_chars()
364 if (up->port.cons != NULL && in receive_chars()
365 up->port.line == up->port.cons->index) { in receive_chars()
367 *status |= up->lsr_break_flag; in receive_chars()
368 up->lsr_break_flag = 0; in receive_chars()
378 if (uart_handle_sysrq_char(&up->port, ch)) in receive_chars()
380 if ((*status & up->port.ignore_status_mask) == 0) in receive_chars()
390 *status = serial_inp(up, UART_LSR); in receive_chars()
391 } while ((*status & UART_LSR_DR) && (max_count-- > 0)); in receive_chars()
397 static void transmit_chars(struct uart_sunsu_port *up) in transmit_chars() argument
399 struct tty_port *tport = &up->port.state->port; in transmit_chars()
403 if (up->port.x_char) { in transmit_chars()
404 serial_outp(up, UART_TX, up->port.x_char); in transmit_chars()
405 up->port.icount.tx++; in transmit_chars()
406 up->port.x_char = 0; in transmit_chars()
409 if (uart_tx_stopped(&up->port)) { in transmit_chars()
410 sunsu_stop_tx(&up->port); in transmit_chars()
413 if (kfifo_is_empty(&tport->xmit_fifo)) { in transmit_chars()
414 __stop_tx(up); in transmit_chars()
418 count = up->port.fifosize; in transmit_chars()
420 if (!uart_fifo_get(&up->port, &ch)) in transmit_chars()
423 serial_out(up, UART_TX, ch); in transmit_chars()
424 } while (--count > 0); in transmit_chars()
426 if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) in transmit_chars()
427 uart_write_wakeup(&up->port); in transmit_chars()
429 if (kfifo_is_empty(&tport->xmit_fifo)) in transmit_chars()
430 __stop_tx(up); in transmit_chars()
433 static void check_modem_status(struct uart_sunsu_port *up) in check_modem_status() argument
437 status = serial_in(up, UART_MSR); in check_modem_status()
443 up->port.icount.rng++; in check_modem_status()
445 up->port.icount.dsr++; in check_modem_status()
447 uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); in check_modem_status()
449 uart_handle_cts_change(&up->port, status & UART_MSR_CTS); in check_modem_status()
451 wake_up_interruptible(&up->port.state->port.delta_msr_wait); in check_modem_status()
456 struct uart_sunsu_port *up = dev_id; in sunsu_serial_interrupt() local
460 uart_port_lock_irqsave(&up->port, &flags); in sunsu_serial_interrupt()
463 status = serial_inp(up, UART_LSR); in sunsu_serial_interrupt()
465 receive_chars(up, &status); in sunsu_serial_interrupt()
466 check_modem_status(up); in sunsu_serial_interrupt()
468 transmit_chars(up); in sunsu_serial_interrupt()
470 tty_flip_buffer_push(&up->port.state->port); in sunsu_serial_interrupt()
472 } while (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT)); in sunsu_serial_interrupt()
474 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_serial_interrupt()
485 static void sunsu_change_mouse_baud(struct uart_sunsu_port *up) in sunsu_change_mouse_baud() argument
487 unsigned int cur_cflag = up->cflag; in sunsu_change_mouse_baud()
490 up->cflag &= ~CBAUD; in sunsu_change_mouse_baud()
491 up->cflag |= suncore_mouse_baud_cflag_next(cur_cflag, &new_baud); in sunsu_change_mouse_baud()
493 quot = up->port.uartclk / (16 * new_baud); in sunsu_change_mouse_baud()
495 sunsu_change_speed(&up->port, up->cflag, 0, quot); in sunsu_change_mouse_baud()
498 static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break) in receive_kbd_ms_chars() argument
501 unsigned char ch = serial_inp(up, UART_RX); in receive_kbd_ms_chars()
503 /* Stop-A is handled by drivers/char/keyboard.c now. */ in receive_kbd_ms_chars()
504 if (up->su_type == SU_PORT_KBD) { in receive_kbd_ms_chars()
506 serio_interrupt(&up->serio, ch, 0); in receive_kbd_ms_chars()
508 } else if (up->su_type == SU_PORT_MS) { in receive_kbd_ms_chars()
513 sunsu_change_mouse_baud(up); in receive_kbd_ms_chars()
520 serio_interrupt(&up->serio, ch, 0); in receive_kbd_ms_chars()
525 } while (serial_in(up, UART_LSR) & UART_LSR_DR); in receive_kbd_ms_chars()
530 struct uart_sunsu_port *up = dev_id; in sunsu_kbd_ms_interrupt() local
532 if (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT)) { in sunsu_kbd_ms_interrupt()
533 unsigned char status = serial_inp(up, UART_LSR); in sunsu_kbd_ms_interrupt()
536 receive_kbd_ms_chars(up, (status & UART_LSR_BI) != 0); in sunsu_kbd_ms_interrupt()
544 struct uart_sunsu_port *up = in sunsu_tx_empty() local
549 uart_port_lock_irqsave(&up->port, &flags); in sunsu_tx_empty()
550 ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; in sunsu_tx_empty()
551 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_tx_empty()
558 struct uart_sunsu_port *up = in sunsu_get_mctrl() local
563 status = serial_in(up, UART_MSR); in sunsu_get_mctrl()
579 struct uart_sunsu_port *up = in sunsu_set_mctrl() local
594 serial_out(up, UART_MCR, mcr); in sunsu_set_mctrl()
599 struct uart_sunsu_port *up = in sunsu_break_ctl() local
603 uart_port_lock_irqsave(&up->port, &flags); in sunsu_break_ctl()
604 if (break_state == -1) in sunsu_break_ctl()
605 up->lcr |= UART_LCR_SBC; in sunsu_break_ctl()
607 up->lcr &= ~UART_LCR_SBC; in sunsu_break_ctl()
608 serial_out(up, UART_LCR, up->lcr); in sunsu_break_ctl()
609 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_break_ctl()
614 struct uart_sunsu_port *up = in sunsu_startup() local
619 if (up->port.type == PORT_16C950) { in sunsu_startup()
620 /* Wake up and initialize UART */ in sunsu_startup()
621 up->acr = 0; in sunsu_startup()
622 serial_outp(up, UART_LCR, 0xBF); in sunsu_startup()
623 serial_outp(up, UART_EFR, UART_EFR_ECB); in sunsu_startup()
624 serial_outp(up, UART_IER, 0); in sunsu_startup()
625 serial_outp(up, UART_LCR, 0); in sunsu_startup()
626 serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ in sunsu_startup()
627 serial_outp(up, UART_LCR, 0xBF); in sunsu_startup()
628 serial_outp(up, UART_EFR, UART_EFR_ECB); in sunsu_startup()
629 serial_outp(up, UART_LCR, 0); in sunsu_startup()
634 * If this is an RSA port, see if we can kick it up to the in sunsu_startup()
637 enable_rsa(up); in sunsu_startup()
644 if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) { in sunsu_startup()
645 serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); in sunsu_startup()
646 serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | in sunsu_startup()
648 serial_outp(up, UART_FCR, 0); in sunsu_startup()
654 (void) serial_inp(up, UART_LSR); in sunsu_startup()
655 (void) serial_inp(up, UART_RX); in sunsu_startup()
656 (void) serial_inp(up, UART_IIR); in sunsu_startup()
657 (void) serial_inp(up, UART_MSR); in sunsu_startup()
664 if (!(up->port.flags & UPF_BUGGY_UART) && in sunsu_startup()
665 (serial_inp(up, UART_LSR) == 0xff)) { in sunsu_startup()
666 printk("ttyS%d: LSR safety check engaged!\n", up->port.line); in sunsu_startup()
667 return -ENODEV; in sunsu_startup()
670 if (up->su_type != SU_PORT_PORT) { in sunsu_startup()
671 retval = request_irq(up->port.irq, sunsu_kbd_ms_interrupt, in sunsu_startup()
672 IRQF_SHARED, su_typev[up->su_type], up); in sunsu_startup()
674 retval = request_irq(up->port.irq, sunsu_serial_interrupt, in sunsu_startup()
675 IRQF_SHARED, su_typev[up->su_type], up); in sunsu_startup()
678 printk("su: Cannot register IRQ %d\n", up->port.irq); in sunsu_startup()
685 serial_outp(up, UART_LCR, UART_LCR_WLEN8); in sunsu_startup()
687 uart_port_lock_irqsave(&up->port, &flags); in sunsu_startup()
689 up->port.mctrl |= TIOCM_OUT2; in sunsu_startup()
691 sunsu_set_mctrl(&up->port, up->port.mctrl); in sunsu_startup()
692 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_startup()
699 up->ier = UART_IER_RLSI | UART_IER_RDI; in sunsu_startup()
700 serial_outp(up, UART_IER, up->ier); in sunsu_startup()
702 if (up->port.flags & UPF_FOURPORT) { in sunsu_startup()
707 icp = (up->port.iobase & 0xfe0) | 0x01f; in sunsu_startup()
715 (void) serial_inp(up, UART_LSR); in sunsu_startup()
716 (void) serial_inp(up, UART_RX); in sunsu_startup()
717 (void) serial_inp(up, UART_IIR); in sunsu_startup()
718 (void) serial_inp(up, UART_MSR); in sunsu_startup()
725 struct uart_sunsu_port *up = in sunsu_shutdown() local
732 up->ier = 0; in sunsu_shutdown()
733 serial_outp(up, UART_IER, 0); in sunsu_shutdown()
735 uart_port_lock_irqsave(&up->port, &flags); in sunsu_shutdown()
736 if (up->port.flags & UPF_FOURPORT) { in sunsu_shutdown()
738 inb((up->port.iobase & 0xfe0) | 0x1f); in sunsu_shutdown()
739 up->port.mctrl |= TIOCM_OUT1; in sunsu_shutdown()
741 up->port.mctrl &= ~TIOCM_OUT2; in sunsu_shutdown()
743 sunsu_set_mctrl(&up->port, up->port.mctrl); in sunsu_shutdown()
744 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_shutdown()
749 serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC); in sunsu_shutdown()
750 serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | in sunsu_shutdown()
753 serial_outp(up, UART_FCR, 0); in sunsu_shutdown()
757 * Reset the RSA board back to 115kbps compat mode. in sunsu_shutdown()
759 disable_rsa(up); in sunsu_shutdown()
763 * Read data port to reset things. in sunsu_shutdown()
765 (void) serial_in(up, UART_RX); in sunsu_shutdown()
767 free_irq(up->port.irq, up); in sunsu_shutdown()
774 struct uart_sunsu_port *up = in sunsu_change_speed() local
806 * chip which causes it to seriously miscalculate baud rates in sunsu_change_speed()
809 if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 && in sunsu_change_speed()
810 up->rev == 0x5201) in sunsu_change_speed()
813 if (uart_config[up->port.type].flags & UART_USE_FIFO) { in sunsu_change_speed()
814 if ((up->port.uartclk / quot) < (2400 * 16)) in sunsu_change_speed()
817 else if (up->port.type == PORT_RSA) in sunsu_change_speed()
823 if (up->port.type == PORT_16750) in sunsu_change_speed()
830 uart_port_lock_irqsave(&up->port, &flags); in sunsu_change_speed()
833 * Update the per-port timeout. in sunsu_change_speed()
835 uart_update_timeout(port, cflag, (port->uartclk / (16 * quot))); in sunsu_change_speed()
837 up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; in sunsu_change_speed()
839 up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; in sunsu_change_speed()
841 up->port.read_status_mask |= UART_LSR_BI; in sunsu_change_speed()
844 * Characteres to ignore in sunsu_change_speed()
846 up->port.ignore_status_mask = 0; in sunsu_change_speed()
848 up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; in sunsu_change_speed()
850 up->port.ignore_status_mask |= UART_LSR_BI; in sunsu_change_speed()
856 up->port.ignore_status_mask |= UART_LSR_OE; in sunsu_change_speed()
863 up->port.ignore_status_mask |= UART_LSR_DR; in sunsu_change_speed()
868 up->ier &= ~UART_IER_MSI; in sunsu_change_speed()
869 if (UART_ENABLE_MS(&up->port, cflag)) in sunsu_change_speed()
870 up->ier |= UART_IER_MSI; in sunsu_change_speed()
872 serial_out(up, UART_IER, up->ier); in sunsu_change_speed()
874 if (uart_config[up->port.type].flags & UART_STARTECH) { in sunsu_change_speed()
875 serial_outp(up, UART_LCR, 0xBF); in sunsu_change_speed()
876 serial_outp(up, UART_EFR, cflag & CRTSCTS ? UART_EFR_CTS :0); in sunsu_change_speed()
878 serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ in sunsu_change_speed()
879 serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */ in sunsu_change_speed()
880 serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */ in sunsu_change_speed()
881 if (up->port.type == PORT_16750) in sunsu_change_speed()
882 serial_outp(up, UART_FCR, fcr); /* set fcr */ in sunsu_change_speed()
883 serial_outp(up, UART_LCR, cval); /* reset DLAB */ in sunsu_change_speed()
884 up->lcr = cval; /* Save LCR */ in sunsu_change_speed()
885 if (up->port.type != PORT_16750) { in sunsu_change_speed()
888 serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); in sunsu_change_speed()
890 serial_outp(up, UART_FCR, fcr); /* set fcr */ in sunsu_change_speed()
893 up->cflag = cflag; in sunsu_change_speed()
895 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_change_speed()
905 * Ask the core to calculate the divisor for us. in sunsu_set_termios()
907 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); in sunsu_set_termios()
910 sunsu_change_speed(port, termios->c_cflag, termios->c_iflag, quot); in sunsu_set_termios()
924 struct uart_sunsu_port *up = in sunsu_config_port() local
929 * We are supposed to call autoconfig here, but this requires in sunsu_config_port()
933 port->type = up->type_probed; /* XXX */ in sunsu_config_port()
940 return -EINVAL; in sunsu_verify_port()
946 int type = port->type; in sunsu_type()
983 struct uart_sunsu_port *up = serio->port_data; in sunsu_serio_write() local
990 lsr = serial_in(up, UART_LSR); in sunsu_serio_write()
994 serial_out(up, UART_TX, ch); in sunsu_serio_write()
1003 struct uart_sunsu_port *up = serio->port_data; in sunsu_serio_open() local
1008 if (!up->serio_open) { in sunsu_serio_open()
1009 up->serio_open = 1; in sunsu_serio_open()
1012 ret = -EBUSY; in sunsu_serio_open()
1020 struct uart_sunsu_port *up = serio->port_data; in sunsu_serio_close() local
1024 up->serio_open = 0; in sunsu_serio_close()
1030 static void sunsu_autoconfig(struct uart_sunsu_port *up) in sunsu_autoconfig() argument
1036 if (up->su_type == SU_PORT_NONE) in sunsu_autoconfig()
1039 up->type_probed = PORT_UNKNOWN; in sunsu_autoconfig()
1040 up->port.iotype = UPIO_MEM; in sunsu_autoconfig()
1042 uart_port_lock_irqsave(&up->port, &flags); in sunsu_autoconfig()
1044 if (!(up->port.flags & UPF_BUGGY_UART)) { in sunsu_autoconfig()
1049 * 0x80 is used as a nonsense port to prevent against false in sunsu_autoconfig()
1050 * positives due to ISA bus float. The assumption is that in sunsu_autoconfig()
1051 * 0x80 is a non-existent port; which should be safe since in sunsu_autoconfig()
1054 scratch = serial_inp(up, UART_IER); in sunsu_autoconfig()
1055 serial_outp(up, UART_IER, 0); in sunsu_autoconfig()
1059 scratch2 = serial_inp(up, UART_IER); in sunsu_autoconfig()
1060 serial_outp(up, UART_IER, 0x0f); in sunsu_autoconfig()
1064 scratch3 = serial_inp(up, UART_IER); in sunsu_autoconfig()
1065 serial_outp(up, UART_IER, scratch); in sunsu_autoconfig()
1070 save_mcr = serial_in(up, UART_MCR); in sunsu_autoconfig()
1071 save_lcr = serial_in(up, UART_LCR); in sunsu_autoconfig()
1074 * Check to see if a UART is really there. Certain broken in sunsu_autoconfig()
1079 * manufacturer would be stupid enough to design a board in sunsu_autoconfig()
1080 * that conflicts with COM 1-4 --- we hope! in sunsu_autoconfig()
1082 if (!(up->port.flags & UPF_SKIP_TEST)) { in sunsu_autoconfig()
1083 serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A); in sunsu_autoconfig()
1084 status1 = serial_inp(up, UART_MSR) & 0xF0; in sunsu_autoconfig()
1085 serial_outp(up, UART_MCR, save_mcr); in sunsu_autoconfig()
1089 serial_outp(up, UART_LCR, 0xBF); /* set up for StarTech test */ in sunsu_autoconfig()
1090 serial_outp(up, UART_EFR, 0); /* EFR is the same as FCR */ in sunsu_autoconfig()
1091 serial_outp(up, UART_LCR, 0); in sunsu_autoconfig()
1092 serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); in sunsu_autoconfig()
1093 scratch = serial_in(up, UART_IIR) >> 6; in sunsu_autoconfig()
1096 up->port.type = PORT_16450; in sunsu_autoconfig()
1099 up->port.type = PORT_UNKNOWN; in sunsu_autoconfig()
1102 up->port.type = PORT_16550; in sunsu_autoconfig()
1105 up->port.type = PORT_16550A; in sunsu_autoconfig()
1108 if (up->port.type == PORT_16550A) { in sunsu_autoconfig()
1110 serial_outp(up, UART_LCR, UART_LCR_DLAB); in sunsu_autoconfig()
1111 if (serial_in(up, UART_EFR) == 0) { in sunsu_autoconfig()
1112 up->port.type = PORT_16650; in sunsu_autoconfig()
1114 serial_outp(up, UART_LCR, 0xBF); in sunsu_autoconfig()
1115 if (serial_in(up, UART_EFR) == 0) in sunsu_autoconfig()
1116 up->port.type = PORT_16650V2; in sunsu_autoconfig()
1119 if (up->port.type == PORT_16550A) { in sunsu_autoconfig()
1121 serial_outp(up, UART_LCR, save_lcr | UART_LCR_DLAB); in sunsu_autoconfig()
1122 serial_outp(up, UART_FCR, in sunsu_autoconfig()
1124 scratch = serial_in(up, UART_IIR) >> 5; in sunsu_autoconfig()
1132 serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); in sunsu_autoconfig()
1133 serial_outp(up, UART_LCR, 0); in sunsu_autoconfig()
1134 serial_outp(up, UART_FCR, in sunsu_autoconfig()
1136 scratch = serial_in(up, UART_IIR) >> 5; in sunsu_autoconfig()
1138 up->port.type = PORT_16750; in sunsu_autoconfig()
1140 serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); in sunsu_autoconfig()
1142 serial_outp(up, UART_LCR, save_lcr); in sunsu_autoconfig()
1143 if (up->port.type == PORT_16450) { in sunsu_autoconfig()
1144 scratch = serial_in(up, UART_SCR); in sunsu_autoconfig()
1145 serial_outp(up, UART_SCR, 0xa5); in sunsu_autoconfig()
1146 status1 = serial_in(up, UART_SCR); in sunsu_autoconfig()
1147 serial_outp(up, UART_SCR, 0x5a); in sunsu_autoconfig()
1148 status2 = serial_in(up, UART_SCR); in sunsu_autoconfig()
1149 serial_outp(up, UART_SCR, scratch); in sunsu_autoconfig()
1152 up->port.type = PORT_8250; in sunsu_autoconfig()
1155 up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size; in sunsu_autoconfig()
1157 if (up->port.type == PORT_UNKNOWN) in sunsu_autoconfig()
1159 up->type_probed = up->port.type; /* XXX */ in sunsu_autoconfig()
1165 if (up->port.type == PORT_RSA) in sunsu_autoconfig()
1166 serial_outp(up, UART_RSA_FRR, 0); in sunsu_autoconfig()
1168 serial_outp(up, UART_MCR, save_mcr); in sunsu_autoconfig()
1169 serial_outp(up, UART_FCR, (UART_FCR_ENABLE_FIFO | in sunsu_autoconfig()
1172 serial_outp(up, UART_FCR, 0); in sunsu_autoconfig()
1173 (void)serial_in(up, UART_RX); in sunsu_autoconfig()
1174 serial_outp(up, UART_IER, 0); in sunsu_autoconfig()
1177 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_autoconfig()
1187 static int sunsu_kbd_ms_init(struct uart_sunsu_port *up) in sunsu_kbd_ms_init() argument
1194 if (up->su_type == SU_PORT_KBD) { in sunsu_kbd_ms_init()
1195 up->cflag = B1200 | CS8 | CLOCAL | CREAD; in sunsu_kbd_ms_init()
1198 up->cflag = B4800 | CS8 | CLOCAL | CREAD; in sunsu_kbd_ms_init()
1201 quot = up->port.uartclk / (16 * baud); in sunsu_kbd_ms_init()
1203 sunsu_autoconfig(up); in sunsu_kbd_ms_init()
1204 if (up->port.type == PORT_UNKNOWN) in sunsu_kbd_ms_init()
1205 return -ENODEV; in sunsu_kbd_ms_init()
1208 up->port.dev->of_node, in sunsu_kbd_ms_init()
1209 (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", in sunsu_kbd_ms_init()
1210 (unsigned long long) up->port.mapbase, in sunsu_kbd_ms_init()
1211 up->port.irq); in sunsu_kbd_ms_init()
1214 serio = &up->serio; in sunsu_kbd_ms_init()
1215 serio->port_data = up; in sunsu_kbd_ms_init()
1217 serio->id.type = SERIO_RS232; in sunsu_kbd_ms_init()
1218 if (up->su_type == SU_PORT_KBD) { in sunsu_kbd_ms_init()
1219 serio->id.proto = SERIO_SUNKBD; in sunsu_kbd_ms_init()
1220 strscpy(serio->name, "sukbd", sizeof(serio->name)); in sunsu_kbd_ms_init()
1222 serio->id.proto = SERIO_SUN; in sunsu_kbd_ms_init()
1223 serio->id.extra = 1; in sunsu_kbd_ms_init()
1224 strscpy(serio->name, "sums", sizeof(serio->name)); in sunsu_kbd_ms_init()
1226 strscpy(serio->phys, in sunsu_kbd_ms_init()
1227 (!(up->port.line & 1) ? "su/serio0" : "su/serio1"), in sunsu_kbd_ms_init()
1228 sizeof(serio->phys)); in sunsu_kbd_ms_init()
1230 serio->write = sunsu_serio_write; in sunsu_kbd_ms_init()
1231 serio->open = sunsu_serio_open; in sunsu_kbd_ms_init()
1232 serio->close = sunsu_serio_close; in sunsu_kbd_ms_init()
1233 serio->dev.parent = up->port.dev; in sunsu_kbd_ms_init()
1238 sunsu_change_speed(&up->port, up->cflag, 0, quot); in sunsu_kbd_ms_init()
1240 sunsu_startup(&up->port); in sunsu_kbd_ms_init()
1245 * ------------------------------------------------------------
1247 * ------------------------------------------------------------
1253 * Wait for transmitter & holding register to empty
1255 static void wait_for_xmitr(struct uart_sunsu_port *up) in wait_for_xmitr() argument
1259 /* Wait up to 10ms for the character(s) to be sent. */ in wait_for_xmitr()
1261 status = serial_in(up, UART_LSR); in wait_for_xmitr()
1264 up->lsr_break_flag = UART_LSR_BI; in wait_for_xmitr()
1266 if (--tmout == 0) in wait_for_xmitr()
1271 /* Wait up to 1s for flow control if necessary */ in wait_for_xmitr()
1272 if (up->port.flags & UPF_CONS_FLOW) { in wait_for_xmitr()
1274 while (--tmout && in wait_for_xmitr()
1275 ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) in wait_for_xmitr()
1282 struct uart_sunsu_port *up = in sunsu_console_putchar() local
1285 wait_for_xmitr(up); in sunsu_console_putchar()
1286 serial_out(up, UART_TX, ch); in sunsu_console_putchar()
1290 * Print a string to the serial port trying not to disturb
1296 struct uart_sunsu_port *up = &sunsu_ports[co->index]; in sunsu_console_write() local
1301 if (up->port.sysrq || oops_in_progress) in sunsu_console_write()
1302 locked = uart_port_trylock_irqsave(&up->port, &flags); in sunsu_console_write()
1304 uart_port_lock_irqsave(&up->port, &flags); in sunsu_console_write()
1309 ier = serial_in(up, UART_IER); in sunsu_console_write()
1310 serial_out(up, UART_IER, 0); in sunsu_console_write()
1312 uart_console_write(&up->port, s, count, sunsu_console_putchar); in sunsu_console_write()
1315 * Finally, wait for transmitter to become empty in sunsu_console_write()
1318 wait_for_xmitr(up); in sunsu_console_write()
1319 serial_out(up, UART_IER, ier); in sunsu_console_write()
1322 uart_port_unlock_irqrestore(&up->port, flags); in sunsu_console_write()
1327 * - construct a cflag setting for the first su_open()
1328 * - initialize the serial port
1329 * Return non-zero if we didn't find a serial port.
1338 (sunsu_reg.minor - 64) + co->index); in sunsu_console_setup()
1340 if (co->index > nr_inst) in sunsu_console_setup()
1341 return -ENODEV; in sunsu_console_setup()
1342 port = &sunsu_ports[co->index].port; in sunsu_console_setup()
1347 spin_lock_init(&port->lock); in sunsu_console_setup()
1350 sunserial_console_termios(co, port->dev->of_node); in sunsu_console_setup()
1353 termios.c_cflag = co->cflag; in sunsu_console_setup()
1354 port->mctrl |= TIOCM_DTR; in sunsu_console_setup()
1355 port->ops->set_termios(port, &termios, &dummy); in sunsu_console_setup()
1366 .index = -1,
1412 struct device_node *dp = op->dev.of_node; in su_probe()
1413 struct uart_sunsu_port *up; in su_probe() local
1422 return -EINVAL; in su_probe()
1423 up = &sunsu_ports[nr_inst]; in su_probe()
1425 up = kzalloc(sizeof(*up), GFP_KERNEL); in su_probe()
1426 if (!up) in su_probe()
1427 return -ENOMEM; in su_probe()
1430 up->port.line = nr_inst; in su_probe()
1432 spin_lock_init(&up->port.lock); in su_probe()
1434 up->su_type = type; in su_probe()
1436 rp = &op->resource[0]; in su_probe()
1437 up->port.mapbase = rp->start; in su_probe()
1438 up->reg_size = resource_size(rp); in su_probe()
1439 up->port.membase = of_ioremap(rp, 0, up->reg_size, "su"); in su_probe()
1440 if (!up->port.membase) { in su_probe()
1442 kfree(up); in su_probe()
1443 return -ENOMEM; in su_probe()
1446 up->port.irq = op->archdata.irqs[0]; in su_probe()
1448 up->port.dev = &op->dev; in su_probe()
1450 up->port.type = PORT_UNKNOWN; in su_probe()
1451 up->port.uartclk = (SU_BASE_BAUD * 16); in su_probe()
1452 up->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SUNSU_CONSOLE); in su_probe()
1455 if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { in su_probe()
1456 err = sunsu_kbd_ms_init(up); in su_probe()
1458 of_iounmap(&op->resource[0], in su_probe()
1459 up->port.membase, up->reg_size); in su_probe()
1460 kfree(up); in su_probe()
1463 platform_set_drvdata(op, up); in su_probe()
1470 up->port.flags |= UPF_BOOT_AUTOCONF; in su_probe()
1472 sunsu_autoconfig(up); in su_probe()
1474 err = -ENODEV; in su_probe()
1475 if (up->port.type == PORT_UNKNOWN) in su_probe()
1478 up->port.ops = &sunsu_pops; in su_probe()
1481 if (of_node_name_eq(dp, "rsc-console") || in su_probe()
1482 of_node_name_eq(dp, "lom-console")) in su_probe()
1486 &sunsu_reg, up->port.line, in su_probe()
1488 err = uart_add_one_port(&sunsu_reg, &up->port); in su_probe()
1492 platform_set_drvdata(op, up); in su_probe()
1499 of_iounmap(&op->resource[0], up->port.membase, up->reg_size); in su_probe()
1500 kfree(up); in su_probe()
1506 struct uart_sunsu_port *up = platform_get_drvdata(op); in su_remove() local
1509 if (up->su_type == SU_PORT_MS || in su_remove()
1510 up->su_type == SU_PORT_KBD) in su_remove()
1515 serio_unregister_port(&up->serio); in su_remove()
1517 } else if (up->port.type != PORT_UNKNOWN) in su_remove()
1518 uart_remove_one_port(&sunsu_reg, &up->port); in su_remove()
1520 if (up->port.membase) in su_remove()
1521 of_iounmap(&op->resource[0], up->port.membase, up->reg_size); in su_remove()
1524 kfree(up); in su_remove()