Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);