^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ** mux.c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) ** serial driver for the Mux console found in some PA-RISC servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ** (c) Copyright 2002 Ryan Bradetich
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) ** (c) Copyright 2002 Hewlett-Packard Company
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) ** This Driver currently only supports the console (port 0) on the MUX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) ** Additional work will be needed on this driver to enable the full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) ** functionality of the MUX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/delay.h> /* for udelay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/parisc-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/sysrq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MUX_OFFSET 0x800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MUX_LINE_OFFSET 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MUX_FIFO_SIZE 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MUX_POLL_DELAY (30 * HZ / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define IO_DATA_REG_OFFSET 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define IO_DCOUNT_REG_OFFSET 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MUX_NR 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static unsigned int port_cnt __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct mux_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct uart_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static struct mux_port mux_ports[MUX_NR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static struct uart_driver mux_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .driver_name = "ttyB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .dev_name = "ttyB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .major = MUX_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .minor = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .nr = MUX_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static struct timer_list mux_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * get_mux_port_count - Get the number of available ports on the Mux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @dev: The parisc device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * This function is used to determine the number of ports the Mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * supports. The IODC data reports the number of ports the Mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * can support, but there are cases where not all the Mux ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * are connected. This function can override the IODC and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * return the true port count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int __init get_mux_port_count(struct parisc_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u8 iodc_data[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) unsigned long bytecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* If this is the built-in Mux for the K-Class (Eole CAP/MUX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * we only need to allocate resources for 1 port since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * other 7 ports are not connected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if(dev->id.hversion == 0x15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) BUG_ON(status != PDC_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Return the number of ports specified in the iodc data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * mux_tx_empty - Check if the transmitter fifo is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * This function test if the transmitter fifo for the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * described by 'port' is empty. If it is empty, this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * should return TIOCSER_TEMT, otherwise return 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static unsigned int mux_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return UART_GET_FIFO_CNT(port) ? 0 : TIOCSER_TEMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * mux_set_mctrl - Set the current state of the modem control inputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @ports: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @mctrl: Modem control bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * The Serial MUX does not support CTS, DCD or DSR so this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * is ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void mux_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * mux_get_mctrl - Returns the current state of modem control inputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * The Serial MUX does not support CTS, DCD or DSR so these lines are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * treated as permanently active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static unsigned int mux_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * mux_stop_tx - Stop transmitting characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * The Serial MUX does not support this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static void mux_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * mux_start_tx - Start transmitting characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * The Serial Mux does not support this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static void mux_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * mux_stop_rx - Stop receiving characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * The Serial Mux does not support this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static void mux_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * mux_break_ctl - Control the transmitssion of a break signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * @break_state: Raise/Lower the break signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * The Serial Mux does not support this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void mux_break_ctl(struct uart_port *port, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * mux_write - Write chars to the mux fifo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * This function writes all the data from the uart buffer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * the mux fifo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static void mux_write(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if(port->x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) UART_PUT_CHAR(port, port->x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if(uart_circ_empty(xmit) || uart_tx_stopped(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mux_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) count = (port->fifosize) - UART_GET_FIFO_CNT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if(uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } while(--count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) while(UART_GET_FIFO_CNT(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) uart_write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) mux_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * mux_read - Read chars from the mux fifo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * This reads all available data from the mux's fifo and pushes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * the data to the tty layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void mux_read(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct tty_port *tport = &port->state->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) __u32 start_count = port->icount.rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) while(1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) data = __raw_readl(port->membase + IO_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (MUX_STATUS(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (MUX_EOFIFO(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) port->icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (MUX_BREAK(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if(uart_handle_break(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (uart_handle_sysrq_char(port, data & 0xffu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) tty_insert_flip_char(tport, data & 0xFF, TTY_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (start_count != port->icount.rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) tty_flip_buffer_push(tport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * mux_startup - Initialize the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Grab any resources needed for this port and start the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * mux timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int mux_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) mux_ports[port->line].enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * mux_shutdown - Disable the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * Release any resources needed for the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static void mux_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) mux_ports[port->line].enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * mux_set_termios - Chane port parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * @termios: new termios settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * @old: old termios settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * The Serial Mux does not support this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) mux_set_termios(struct uart_port *port, struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * mux_type - Describe the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * Return a pointer to a string constant describing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * specified port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static const char *mux_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return "Mux";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * mux_release_port - Release memory and IO regions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * Release any memory and IO region resources currently in use by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static void mux_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * mux_request_port - Request memory and IO regions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Request any memory and IO region resources required by the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * If any fail, no resources should be registered when this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * returns, and it should return -EBUSY on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int mux_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * mux_config_port - Perform port autoconfiguration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * @type: Bitmask of required configurations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Perform any autoconfiguration steps for the port. This function is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * called if the UPF_BOOT_AUTOCONF flag is specified for the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * [Note: This is required for now because of a bug in the Serial core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * rmk has already submitted a patch to linus, should be available for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * 2.5.47.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static void mux_config_port(struct uart_port *port, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) port->type = PORT_MUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * mux_verify_port - Verify the port information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * @port: Ptr to the uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * @ser: Ptr to the serial information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * Verify the new serial port information contained within serinfo is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * suitable for this port type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int mux_verify_port(struct uart_port *port, struct serial_struct *ser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if(port->membase == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * mux_drv_poll - Mux poll function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * @unused: Unused variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * This function periodically polls the Serial MUX to check for new data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static void mux_poll(struct timer_list *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) for(i = 0; i < port_cnt; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if(!mux_ports[i].enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) mux_read(&mux_ports[i].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mux_write(&mux_ports[i].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #ifdef CONFIG_SERIAL_MUX_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static void mux_console_write(struct console *co, const char *s, unsigned count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* Wait until the FIFO drains. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) while(UART_GET_FIFO_CNT(&mux_ports[0].port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) while(count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if(*s == '\n') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) UART_PUT_CHAR(&mux_ports[0].port, '\r');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) UART_PUT_CHAR(&mux_ports[0].port, *s++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static int mux_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static struct console mux_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .name = "ttyB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .write = mux_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .setup = mux_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .flags = CON_ENABLED | CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .data = &mux_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #define MUX_CONSOLE &mux_console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #define MUX_CONSOLE NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static const struct uart_ops mux_pops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .tx_empty = mux_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .set_mctrl = mux_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .get_mctrl = mux_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .stop_tx = mux_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .start_tx = mux_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .stop_rx = mux_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .break_ctl = mux_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .startup = mux_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .shutdown = mux_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .set_termios = mux_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .type = mux_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .release_port = mux_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .request_port = mux_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .config_port = mux_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .verify_port = mux_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * mux_probe - Determine if the Serial Mux should claim this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * @dev: The parisc device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * Deterimine if the Serial Mux should claim this chip (return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * or not (return 1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int __init mux_probe(struct parisc_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int i, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int port_count = get_mux_port_count(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.6\n", port_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) dev_set_drvdata(&dev->dev, (void *)(long)port_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) request_mem_region(dev->hpa.start + MUX_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) port_count * MUX_LINE_OFFSET, "Mux");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if(!port_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) mux_driver.cons = MUX_CONSOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) status = uart_register_driver(&mux_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if(status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) printk(KERN_ERR "Serial mux: Unable to register driver.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) for(i = 0; i < port_count; ++i, ++port_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct uart_port *port = &mux_ports[port_cnt].port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) port->iobase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) port->mapbase = dev->hpa.start + MUX_OFFSET +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) (i * MUX_LINE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) port->iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) port->type = PORT_MUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) port->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) port->uartclk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) port->fifosize = MUX_FIFO_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) port->ops = &mux_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) port->flags = UPF_BOOT_AUTOCONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) port->line = port_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MUX_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* The port->timeout needs to match what is present in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * uart_wait_until_sent in serial_core.c. Otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * the time spent in msleep_interruptable will be very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * long, causing the appearance of a console hang.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) port->timeout = HZ / 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) spin_lock_init(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) status = uart_add_one_port(&mux_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) BUG_ON(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static int __exit mux_remove(struct parisc_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int port_count = (long)dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Find Port 0 for this card in the mux_ports list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) for(i = 0; i < port_cnt; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if(mux_ports[i].port.mapbase == dev->hpa.start + MUX_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) BUG_ON(i + port_count > port_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* Release the resources associated with each port on the device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) for(j = 0; j < port_count; ++j, ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct uart_port *port = &mux_ports[i].port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) uart_remove_one_port(&mux_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if(port->membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) iounmap(port->membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) release_mem_region(dev->hpa.start + MUX_OFFSET, port_count * MUX_LINE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* Hack. This idea was taken from the 8250_gsc.c on how to properly order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * the serial port detection in the proper order. The idea is we always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * want the builtin mux to be detected before addin mux cards, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * specifically probe for the builtin mux cards first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * This table only contains the parisc_device_id of known builtin mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * devices. All other mux cards will be detected by the generic mux_tbl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static const struct parisc_device_id builtin_mux_tbl[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static const struct parisc_device_id mux_tbl[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) MODULE_DEVICE_TABLE(parisc, mux_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static struct parisc_driver builtin_serial_mux_driver __refdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .name = "builtin_serial_mux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .id_table = builtin_mux_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .probe = mux_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .remove = __exit_p(mux_remove),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static struct parisc_driver serial_mux_driver __refdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .name = "serial_mux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .id_table = mux_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .probe = mux_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .remove = __exit_p(mux_remove),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * mux_init - Serial MUX initialization procedure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * Register the Serial MUX driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static int __init mux_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) register_parisc_driver(&builtin_serial_mux_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) register_parisc_driver(&serial_mux_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if(port_cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* Start the Mux timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) timer_setup(&mux_timer, mux_poll, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #ifdef CONFIG_SERIAL_MUX_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) register_console(&mux_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * mux_exit - Serial MUX cleanup procedure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * Unregister the Serial MUX driver from the tty layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static void __exit mux_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* Delete the Mux timer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if(port_cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) del_timer_sync(&mux_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #ifdef CONFIG_SERIAL_MUX_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) unregister_console(&mux_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) unregister_parisc_driver(&builtin_serial_mux_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) unregister_parisc_driver(&serial_mux_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) uart_unregister_driver(&mux_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) module_init(mux_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) module_exit(mux_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) MODULE_AUTHOR("Ryan Bradetich");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) MODULE_DESCRIPTION("Serial MUX driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) MODULE_ALIAS_CHARDEV_MAJOR(MUX_MAJOR);