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