1 /*
2  * drivers/char/vme_scc.c: MVME147, MVME162, BVME6000 SCC serial ports
3  * implementation.
4  * Copyright 1999 Richard Hirst <richard@sleepie.demon.co.uk>
5  *
6  * Based on atari_SCC.c which was
7  *   Copyright 1994-95 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
8  *   Partially based on PC-Linux serial.c by Linus Torvalds and Theodore Ts'o
9  *
10  * This file is subject to the terms and conditions of the GNU General Public
11  * License.  See the file COPYING in the main directory of this archive
12  * for more details.
13  *
14  */
15 
16 #include <linux/module.h>
17 #include <linux/config.h>
18 #include <linux/kdev_t.h>
19 #include <asm/io.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/ioport.h>
23 #include <linux/interrupt.h>
24 #include <linux/errno.h>
25 #include <linux/tty.h>
26 #include <linux/tty_flip.h>
27 #include <linux/mm.h>
28 #include <linux/serial.h>
29 #include <linux/fcntl.h>
30 #include <linux/major.h>
31 #include <linux/delay.h>
32 #include <linux/tqueue.h>
33 #include <linux/version.h>
34 #include <linux/slab.h>
35 #include <linux/miscdevice.h>
36 #include <linux/console.h>
37 #include <linux/init.h>
38 #include <asm/setup.h>
39 #include <asm/bootinfo.h>
40 
41 #ifdef CONFIG_MVME147_SCC
42 #include <asm/mvme147hw.h>
43 #endif
44 #ifdef CONFIG_MVME162_SCC
45 #include <asm/mvme16xhw.h>
46 #endif
47 #ifdef CONFIG_BVME6000_SCC
48 #include <asm/bvme6000hw.h>
49 #endif
50 
51 #include <linux/generic_serial.h>
52 #include "scc.h"
53 
54 
55 #define CHANNEL_A	0
56 #define CHANNEL_B	1
57 
58 #define SCC_MINOR_BASE	64
59 
60 /* Shadows for all SCC write registers */
61 static unsigned char scc_shadow[2][16];
62 
63 /* Location to access for SCC register access delay */
64 static volatile unsigned char *scc_del = NULL;
65 
66 /* To keep track of STATUS_REG state for detection of Ext/Status int source */
67 static unsigned char scc_last_status_reg[2];
68 
69 /***************************** Prototypes *****************************/
70 
71 /* Function prototypes */
72 static void scc_disable_tx_interrupts(void * ptr);
73 static void scc_enable_tx_interrupts(void * ptr);
74 static void scc_disable_rx_interrupts(void * ptr);
75 static void scc_enable_rx_interrupts(void * ptr);
76 static int  scc_get_CD(void * ptr);
77 static void scc_shutdown_port(void * ptr);
78 static int scc_set_real_termios(void  *ptr);
79 static void scc_hungup(void  *ptr);
80 static void scc_close(void  *ptr);
81 static int scc_chars_in_buffer(void * ptr);
82 static int scc_open(struct tty_struct * tty, struct file * filp);
83 static int scc_ioctl(struct tty_struct * tty, struct file * filp,
84                      unsigned int cmd, unsigned long arg);
85 static void scc_throttle(struct tty_struct *tty);
86 static void scc_unthrottle(struct tty_struct *tty);
87 static void scc_tx_int(int irq, void *data, struct pt_regs *fp);
88 static void scc_rx_int(int irq, void *data, struct pt_regs *fp);
89 static void scc_stat_int(int irq, void *data, struct pt_regs *fp);
90 static void scc_spcond_int(int irq, void *data, struct pt_regs *fp);
91 static void scc_setsignals(struct scc_port *port, int dtr, int rts);
92 static void scc_break_ctl(struct tty_struct *tty, int break_state);
93 
94 static struct tty_driver scc_driver, scc_callout_driver;
95 
96 static struct tty_struct *scc_table[2] = { NULL, };
97 static struct termios * scc_termios[2];
98 static struct termios * scc_termios_locked[2];
99 struct scc_port scc_ports[2];
100 
101 int scc_refcount;
102 int scc_initialized = 0;
103 
104 /*---------------------------------------------------------------------------
105  * Interface from generic_serial.c back here
106  *--------------------------------------------------------------------------*/
107 
108 static struct real_driver scc_real_driver = {
109         scc_disable_tx_interrupts,
110         scc_enable_tx_interrupts,
111         scc_disable_rx_interrupts,
112         scc_enable_rx_interrupts,
113         scc_get_CD,
114         scc_shutdown_port,
115         scc_set_real_termios,
116         scc_chars_in_buffer,
117         scc_close,
118         scc_hungup,
119         NULL
120 };
121 
122 
123 /*----------------------------------------------------------------------------
124  * vme_scc_init() and support functions
125  *---------------------------------------------------------------------------*/
126 
scc_init_drivers(void)127 static int scc_init_drivers(void)
128 {
129 	int error;
130 
131 	memset(&scc_driver, 0, sizeof(scc_driver));
132 	scc_driver.magic = TTY_DRIVER_MAGIC;
133 	scc_driver.driver_name = "scc";
134 #ifdef CONFIG_DEVFS_FS
135 	scc_driver.name = "tts/%d";
136 #else
137 	scc_driver.name = "ttyS";
138 #endif
139 	scc_driver.major = TTY_MAJOR;
140 	scc_driver.minor_start = SCC_MINOR_BASE;
141 	scc_driver.num = 2;
142 	scc_driver.type = TTY_DRIVER_TYPE_SERIAL;
143 	scc_driver.subtype = SERIAL_TYPE_NORMAL;
144 	scc_driver.init_termios = tty_std_termios;
145 	scc_driver.init_termios.c_cflag =
146 	  B9600 | CS8 | CREAD | HUPCL | CLOCAL;
147 	scc_driver.flags = TTY_DRIVER_REAL_RAW;
148 	scc_driver.refcount = &scc_refcount;
149 	scc_driver.table = scc_table;
150 	scc_driver.termios = scc_termios;
151 	scc_driver.termios_locked = scc_termios_locked;
152 
153 	scc_driver.open	= scc_open;
154 	scc_driver.close = gs_close;
155 	scc_driver.write = gs_write;
156 	scc_driver.put_char = gs_put_char;
157 	scc_driver.flush_chars = gs_flush_chars;
158 	scc_driver.write_room = gs_write_room;
159 	scc_driver.chars_in_buffer = gs_chars_in_buffer;
160 	scc_driver.flush_buffer = gs_flush_buffer;
161 	scc_driver.ioctl = scc_ioctl;
162 	scc_driver.throttle = scc_throttle;
163 	scc_driver.unthrottle = scc_unthrottle;
164 	scc_driver.set_termios = gs_set_termios;
165 	scc_driver.stop = gs_stop;
166 	scc_driver.start = gs_start;
167 	scc_driver.hangup = gs_hangup;
168 	scc_driver.break_ctl = scc_break_ctl;
169 
170 	scc_callout_driver = scc_driver;
171 #ifdef CONFIG_DEVFS_FS
172 	scc_callout_driver.name = "cua/%d";
173 #else
174 	scc_callout_driver.name = "cua";
175 #endif
176 	scc_callout_driver.major = TTYAUX_MAJOR;
177 	scc_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
178 
179 	if ((error = tty_register_driver(&scc_driver))) {
180 		printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n",
181 		       error);
182 		return 1;
183 	}
184 	if ((error = tty_register_driver(&scc_callout_driver))) {
185 		tty_unregister_driver(&scc_driver);
186 		printk(KERN_ERR "scc: Couldn't register scc callout driver, error = %d\n",
187 		       error);
188 		return 1;
189 	}
190 
191 	return 0;
192 }
193 
194 
195 /* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1).
196  */
197 
scc_init_portstructs(void)198 static void scc_init_portstructs(void)
199 {
200 	struct scc_port *port;
201 	int i;
202 
203 	for (i = 0; i < 2; i++) {
204 		port = scc_ports + i;
205 		port->gs.callout_termios = tty_std_termios;
206 		port->gs.normal_termios = tty_std_termios;
207 		port->gs.magic = SCC_MAGIC;
208 		port->gs.close_delay = HZ/2;
209 		port->gs.closing_wait = 30 * HZ;
210 		port->gs.rd = &scc_real_driver;
211 #ifdef NEW_WRITE_LOCKING
212 		port->gs.port_write_sem = MUTEX;
213 #endif
214 		init_waitqueue_head(&port->gs.open_wait);
215 		init_waitqueue_head(&port->gs.close_wait);
216 	}
217 }
218 
219 
220 #ifdef CONFIG_MVME147_SCC
mvme147_scc_init(void)221 static int mvme147_scc_init(void)
222 {
223 	struct scc_port *port;
224 
225 	printk(KERN_INFO "SCC: MVME147 Serial Driver\n");
226 	/* Init channel A */
227 	port = &scc_ports[0];
228 	port->channel = CHANNEL_A;
229 	port->ctrlp = (volatile unsigned char *)M147_SCC_A_ADDR;
230 	port->datap = port->ctrlp + 1;
231 	port->port_a = &scc_ports[0];
232 	port->port_b = &scc_ports[1];
233 	request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, SA_INTERRUPT,
234 		            "SCC-A TX", port);
235 	request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, SA_INTERRUPT,
236 		            "SCC-A status", port);
237 	request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, SA_INTERRUPT,
238 		            "SCC-A RX", port);
239 	request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, SA_INTERRUPT,
240 		            "SCC-A special cond", port);
241 	{
242 		SCC_ACCESS_INIT(port);
243 
244 		/* disable interrupts for this channel */
245 		SCCwrite(INT_AND_DMA_REG, 0);
246 		/* Set the interrupt vector */
247 		SCCwrite(INT_VECTOR_REG, MVME147_IRQ_SCC_BASE);
248 		/* Interrupt parameters: vector includes status, status low */
249 		SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
250 		SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
251 	}
252 
253 	/* Init channel B */
254 	port = &scc_ports[1];
255 	port->channel = CHANNEL_B;
256 	port->ctrlp = (volatile unsigned char *)M147_SCC_B_ADDR;
257 	port->datap = port->ctrlp + 1;
258 	port->port_a = &scc_ports[0];
259 	port->port_b = &scc_ports[1];
260 	request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, SA_INTERRUPT,
261 		            "SCC-B TX", port);
262 	request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, SA_INTERRUPT,
263 		            "SCC-B status", port);
264 	request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, SA_INTERRUPT,
265 		            "SCC-B RX", port);
266 	request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, SA_INTERRUPT,
267 		            "SCC-B special cond", port);
268 	{
269 		SCC_ACCESS_INIT(port);
270 
271 		/* disable interrupts for this channel */
272 		SCCwrite(INT_AND_DMA_REG, 0);
273 	}
274 
275         /* Ensure interrupts are enabled in the PCC chip */
276         m147_pcc->serial_cntrl=PCC_LEVEL_SERIAL|PCC_INT_ENAB;
277 
278 	/* Initialise the tty driver structures and register */
279 	scc_init_portstructs();
280 	scc_init_drivers();
281 
282 	return 0;
283 }
284 #endif
285 
286 
287 #ifdef CONFIG_MVME162_SCC
mvme162_scc_init(void)288 static int mvme162_scc_init(void)
289 {
290 	struct scc_port *port;
291 
292 	if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA))
293 		return (-ENODEV);
294 
295 	printk(KERN_INFO "SCC: MVME162 Serial Driver\n");
296 	/* Init channel A */
297 	port = &scc_ports[0];
298 	port->channel = CHANNEL_A;
299 	port->ctrlp = (volatile unsigned char *)MVME_SCC_A_ADDR;
300 	port->datap = port->ctrlp + 2;
301 	port->port_a = &scc_ports[0];
302 	port->port_b = &scc_ports[1];
303 	request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, SA_INTERRUPT,
304 		            "SCC-A TX", port);
305 	request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, SA_INTERRUPT,
306 		            "SCC-A status", port);
307 	request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, SA_INTERRUPT,
308 		            "SCC-A RX", port);
309 	request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, SA_INTERRUPT,
310 		            "SCC-A special cond", port);
311 	{
312 		SCC_ACCESS_INIT(port);
313 
314 		/* disable interrupts for this channel */
315 		SCCwrite(INT_AND_DMA_REG, 0);
316 		/* Set the interrupt vector */
317 		SCCwrite(INT_VECTOR_REG, MVME162_IRQ_SCC_BASE);
318 		/* Interrupt parameters: vector includes status, status low */
319 		SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
320 		SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
321 	}
322 
323 	/* Init channel B */
324 	port = &scc_ports[1];
325 	port->channel = CHANNEL_B;
326 	port->ctrlp = (volatile unsigned char *)MVME_SCC_B_ADDR;
327 	port->datap = port->ctrlp + 2;
328 	port->port_a = &scc_ports[0];
329 	port->port_b = &scc_ports[1];
330 	request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, SA_INTERRUPT,
331 		            "SCC-B TX", port);
332 	request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, SA_INTERRUPT,
333 		            "SCC-B status", port);
334 	request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, SA_INTERRUPT,
335 		            "SCC-B RX", port);
336 	request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, SA_INTERRUPT,
337 		            "SCC-B special cond", port);
338 
339 	{
340 		SCC_ACCESS_INIT(port);	/* Either channel will do */
341 
342 		/* disable interrupts for this channel */
343 		SCCwrite(INT_AND_DMA_REG, 0);
344 	}
345 
346         /* Ensure interrupts are enabled in the MC2 chip */
347         *(volatile char *)0xfff4201d = 0x14;
348 
349 	/* Initialise the tty driver structures and register */
350 	scc_init_portstructs();
351 	scc_init_drivers();
352 
353 	return 0;
354 }
355 #endif
356 
357 
358 #ifdef CONFIG_BVME6000_SCC
bvme6000_scc_init(void)359 static int bvme6000_scc_init(void)
360 {
361 	struct scc_port *port;
362 
363 	printk(KERN_INFO "SCC: BVME6000 Serial Driver\n");
364 	/* Init channel A */
365 	port = &scc_ports[0];
366 	port->channel = CHANNEL_A;
367 	port->ctrlp = (volatile unsigned char *)BVME_SCC_A_ADDR;
368 	port->datap = port->ctrlp + 4;
369 	port->port_a = &scc_ports[0];
370 	port->port_b = &scc_ports[1];
371 	request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, SA_INTERRUPT,
372 		            "SCC-A TX", port);
373 	request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, SA_INTERRUPT,
374 		            "SCC-A status", port);
375 	request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, SA_INTERRUPT,
376 		            "SCC-A RX", port);
377 	request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, SA_INTERRUPT,
378 		            "SCC-A special cond", port);
379 	{
380 		SCC_ACCESS_INIT(port);
381 
382 		/* disable interrupts for this channel */
383 		SCCwrite(INT_AND_DMA_REG, 0);
384 		/* Set the interrupt vector */
385 		SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE);
386 		/* Interrupt parameters: vector includes status, status low */
387 		SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
388 		SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
389 	}
390 
391 	/* Init channel B */
392 	port = &scc_ports[1];
393 	port->channel = CHANNEL_B;
394 	port->ctrlp = (volatile unsigned char *)BVME_SCC_B_ADDR;
395 	port->datap = port->ctrlp + 4;
396 	port->port_a = &scc_ports[0];
397 	port->port_b = &scc_ports[1];
398 	request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, SA_INTERRUPT,
399 		            "SCC-B TX", port);
400 	request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, SA_INTERRUPT,
401 		            "SCC-B status", port);
402 	request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, SA_INTERRUPT,
403 		            "SCC-B RX", port);
404 	request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, SA_INTERRUPT,
405 		            "SCC-B special cond", port);
406 
407 	{
408 		SCC_ACCESS_INIT(port);	/* Either channel will do */
409 
410 		/* disable interrupts for this channel */
411 		SCCwrite(INT_AND_DMA_REG, 0);
412 	}
413 
414 	/* Initialise the tty driver structures and register */
415 	scc_init_portstructs();
416 	scc_init_drivers();
417 
418 	return 0;
419 }
420 #endif
421 
422 
vme_scc_init(void)423 int vme_scc_init(void)
424 {
425 	int res = -ENODEV;
426 	static int called = 0;
427 
428 	if (called)
429 		return res;
430 	called = 1;
431 #ifdef CONFIG_MVME147_SCC
432 	if (MACH_IS_MVME147)
433 		res = mvme147_scc_init();
434 #endif
435 #ifdef CONFIG_MVME162_SCC
436 	if (MACH_IS_MVME16x)
437 		res = mvme162_scc_init();
438 #endif
439 #ifdef CONFIG_BVME6000_SCC
440 	if (MACH_IS_BVME6000)
441 		res = bvme6000_scc_init();
442 #endif
443 	return res;
444 }
445 
446 
447 /*---------------------------------------------------------------------------
448  * Interrupt handlers
449  *--------------------------------------------------------------------------*/
450 
scc_rx_int(int irq,void * data,struct pt_regs * fp)451 static void scc_rx_int(int irq, void *data, struct pt_regs *fp)
452 {
453 	unsigned char	ch;
454 	struct scc_port *port = data;
455 	struct tty_struct *tty = port->gs.tty;
456 	SCC_ACCESS_INIT(port);
457 
458 	ch = SCCread_NB(RX_DATA_REG);
459 	if (!tty) {
460 		printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
461 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
462 		return;
463 	}
464 	if (tty->flip.count < TTY_FLIPBUF_SIZE) {
465 		*tty->flip.char_buf_ptr = ch;
466 		*tty->flip.flag_buf_ptr = 0;
467 		tty->flip.flag_buf_ptr++;
468 		tty->flip.char_buf_ptr++;
469 		tty->flip.count++;
470 	}
471 
472 	/* Check if another character is already ready; in that case, the
473 	 * spcond_int() function must be used, because this character may have an
474 	 * error condition that isn't signalled by the interrupt vector used!
475 	 */
476 	if (SCCread(INT_PENDING_REG) &
477 	    (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
478 		scc_spcond_int (irq, data, fp);
479 		return;
480 	}
481 
482 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
483 
484 	tty_flip_buffer_push(tty);
485 }
486 
487 
scc_spcond_int(int irq,void * data,struct pt_regs * fp)488 static void scc_spcond_int(int irq, void *data, struct pt_regs *fp)
489 {
490 	struct scc_port *port = data;
491 	struct tty_struct *tty = port->gs.tty;
492 	unsigned char	stat, ch, err;
493 	int		int_pending_mask = port->channel == CHANNEL_A ?
494 			                   IPR_A_RX : IPR_B_RX;
495 	SCC_ACCESS_INIT(port);
496 
497 	if (!tty) {
498 		printk(KERN_WARNING "scc_spcond_int with NULL tty!\n");
499 		SCCwrite(COMMAND_REG, CR_ERROR_RESET);
500 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
501 		return;
502 	}
503 	do {
504 		stat = SCCread(SPCOND_STATUS_REG);
505 		ch = SCCread_NB(RX_DATA_REG);
506 
507 		if (stat & SCSR_RX_OVERRUN)
508 			err = TTY_OVERRUN;
509 		else if (stat & SCSR_PARITY_ERR)
510 			err = TTY_PARITY;
511 		else if (stat & SCSR_CRC_FRAME_ERR)
512 			err = TTY_FRAME;
513 		else
514 			err = 0;
515 
516 		if (tty->flip.count < TTY_FLIPBUF_SIZE) {
517 			*tty->flip.char_buf_ptr = ch;
518 			*tty->flip.flag_buf_ptr = err;
519 			tty->flip.flag_buf_ptr++;
520 			tty->flip.char_buf_ptr++;
521 			tty->flip.count++;
522 		}
523 
524 		/* ++TeSche: *All* errors have to be cleared manually,
525 		 * else the condition persists for the next chars
526 		 */
527 		if (err)
528 		  SCCwrite(COMMAND_REG, CR_ERROR_RESET);
529 
530 	} while(SCCread(INT_PENDING_REG) & int_pending_mask);
531 
532 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
533 
534 	tty_flip_buffer_push(tty);
535 }
536 
537 
scc_tx_int(int irq,void * data,struct pt_regs * fp)538 static void scc_tx_int(int irq, void *data, struct pt_regs *fp)
539 {
540 	struct scc_port *port = data;
541 	SCC_ACCESS_INIT(port);
542 
543 	if (!port->gs.tty) {
544 		printk(KERN_WARNING "scc_tx_int with NULL tty!\n");
545 		SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
546 		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
547 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
548 		return;
549 	}
550 	while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) {
551 		if (port->x_char) {
552 			SCCwrite(TX_DATA_REG, port->x_char);
553 			port->x_char = 0;
554 		}
555 		else if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
556 				port->gs.tty->hw_stopped)
557 			break;
558 		else {
559 			SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]);
560 			port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1);
561 			if (--port->gs.xmit_cnt <= 0)
562 				break;
563 		}
564 	}
565 	if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
566 			port->gs.tty->hw_stopped) {
567 		/* disable tx interrupts */
568 		SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
569 		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);   /* disable tx_int on next tx underrun? */
570 		port->gs.flags &= ~GS_TX_INTEN;
571 	}
572 	if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars)
573 		tty_wakeup(port->gs.tty);
574 
575 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
576 }
577 
578 
scc_stat_int(int irq,void * data,struct pt_regs * fp)579 static void scc_stat_int(int irq, void *data, struct pt_regs *fp)
580 {
581 	struct scc_port *port = data;
582 	unsigned channel = port->channel;
583 	unsigned char	last_sr, sr, changed;
584 	SCC_ACCESS_INIT(port);
585 
586 	last_sr = scc_last_status_reg[channel];
587 	sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG);
588 	changed = last_sr ^ sr;
589 
590 	if (changed & SR_DCD) {
591 		port->c_dcd = !!(sr & SR_DCD);
592 		if (!(port->gs.flags & ASYNC_CHECK_CD))
593 			;	/* Don't report DCD changes */
594 		else if (port->c_dcd) {
595 			if (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) ||
596 				~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) {
597 				/* Are we blocking in open?*/
598 				wake_up_interruptible(&port->gs.open_wait);
599 			}
600 		}
601 		else {
602 			if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) &&
603 					(port->gs.flags & ASYNC_CALLOUT_NOHUP))) {
604 				if (port->gs.tty)
605 					tty_hangup (port->gs.tty);
606 			}
607 		}
608 	}
609 	SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET);
610 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
611 }
612 
613 
614 /*---------------------------------------------------------------------------
615  * generic_serial.c callback funtions
616  *--------------------------------------------------------------------------*/
617 
scc_disable_tx_interrupts(void * ptr)618 static void scc_disable_tx_interrupts(void *ptr)
619 {
620 	struct scc_port *port = ptr;
621 	unsigned long	flags;
622 	SCC_ACCESS_INIT(port);
623 
624 	save_flags(flags);
625 	cli();
626 	SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
627 	port->gs.flags &= ~GS_TX_INTEN;
628 	restore_flags(flags);
629 }
630 
631 
scc_enable_tx_interrupts(void * ptr)632 static void scc_enable_tx_interrupts(void *ptr)
633 {
634 	struct scc_port *port = ptr;
635 	unsigned long	flags;
636 	SCC_ACCESS_INIT(port);
637 
638 	save_flags(flags);
639 	cli();
640 	SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB);
641 	/* restart the transmitter */
642 	scc_tx_int (0, port, 0);
643 	restore_flags(flags);
644 }
645 
646 
scc_disable_rx_interrupts(void * ptr)647 static void scc_disable_rx_interrupts(void *ptr)
648 {
649 	struct scc_port *port = ptr;
650 	unsigned long	flags;
651 	SCC_ACCESS_INIT(port);
652 
653 	save_flags(flags);
654 	cli();
655 	SCCmod(INT_AND_DMA_REG,
656 	    ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0);
657 	restore_flags(flags);
658 }
659 
660 
scc_enable_rx_interrupts(void * ptr)661 static void scc_enable_rx_interrupts(void *ptr)
662 {
663 	struct scc_port *port = ptr;
664 	unsigned long	flags;
665 	SCC_ACCESS_INIT(port);
666 
667 	save_flags(flags);
668 	cli();
669 	SCCmod(INT_AND_DMA_REG, 0xff,
670 		IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL);
671 	restore_flags(flags);
672 }
673 
674 
scc_get_CD(void * ptr)675 static int scc_get_CD(void *ptr)
676 {
677 	struct scc_port *port = ptr;
678 	unsigned channel = port->channel;
679 
680 	return !!(scc_last_status_reg[channel] & SR_DCD);
681 }
682 
683 
scc_shutdown_port(void * ptr)684 static void scc_shutdown_port(void *ptr)
685 {
686 	struct scc_port *port = ptr;
687 
688 	port->gs.flags &= ~ GS_ACTIVE;
689 	if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) {
690 		scc_setsignals (port, 0, 0);
691 	}
692 }
693 
694 
scc_set_real_termios(void * ptr)695 static int scc_set_real_termios (void *ptr)
696 {
697 	/* the SCC has char sizes 5,7,6,8 in that order! */
698 	static int chsize_map[4] = { 0, 2, 1, 3 };
699 	unsigned cflag, baud, chsize, channel, brgval = 0;
700 	unsigned long flags;
701 	struct scc_port *port = ptr;
702 	SCC_ACCESS_INIT(port);
703 
704 	if (!port->gs.tty || !port->gs.tty->termios) return 0;
705 
706 	channel = port->channel;
707 
708 	if (channel == CHANNEL_A)
709 		return 0;		/* Settings controlled by boot PROM */
710 
711 	cflag  = port->gs.tty->termios->c_cflag;
712 	baud = port->gs.baud;
713 	chsize = (cflag & CSIZE) >> 4;
714 
715 	if (baud == 0) {
716 		/* speed == 0 -> drop DTR */
717 		save_flags(flags);
718 		cli();
719 		SCCmod(TX_CTRL_REG, ~TCR_DTR, 0);
720 		restore_flags(flags);
721 		return 0;
722 	}
723 	else if ((MACH_IS_MVME16x && (baud < 50 || baud > 38400)) ||
724 		 (MACH_IS_MVME147 && (baud < 50 || baud > 19200)) ||
725 		 (MACH_IS_BVME6000 &&(baud < 50 || baud > 76800))) {
726 		printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud);
727 		return 0;
728 	}
729 
730 	if (cflag & CLOCAL)
731 		port->gs.flags &= ~ASYNC_CHECK_CD;
732 	else
733 		port->gs.flags |= ASYNC_CHECK_CD;
734 
735 #ifdef CONFIG_MVME147_SCC
736 	if (MACH_IS_MVME147)
737 		brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
738 #endif
739 #ifdef CONFIG_MVME162_SCC
740 	if (MACH_IS_MVME16x)
741 		brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
742 #endif
743 #ifdef CONFIG_BVME6000_SCC
744 	if (MACH_IS_BVME6000)
745 		brgval = (BVME_SCC_RTxC + baud/2) / (16 * 2 * baud) - 2;
746 #endif
747 	/* Now we have all parameters and can go to set them: */
748 	save_flags(flags);
749 	cli();
750 
751 	/* receiver's character size and auto-enables */
752 	SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE),
753 			(chsize_map[chsize] << 6) |
754 			((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0));
755 	/* parity and stop bits (both, Tx and Rx), clock mode never changes */
756 	SCCmod (AUX1_CTRL_REG,
757 		~(A1CR_PARITY_MASK | A1CR_MODE_MASK),
758 		((cflag & PARENB
759 		  ? (cflag & PARODD ? A1CR_PARITY_ODD : A1CR_PARITY_EVEN)
760 		  : A1CR_PARITY_NONE)
761 		 | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1)));
762 	/* sender's character size, set DTR for valid baud rate */
763 	SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR);
764 	/* clock sources never change */
765 	/* disable BRG before changing the value */
766 	SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0);
767 	/* BRG value */
768 	SCCwrite(TIMER_LOW_REG, brgval & 0xff);
769 	SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff);
770 	/* BRG enable, and clock source never changes */
771 	SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB);
772 
773 	restore_flags(flags);
774 
775 	return 0;
776 }
777 
778 
scc_chars_in_buffer(void * ptr)779 static int scc_chars_in_buffer (void *ptr)
780 {
781 	struct scc_port *port = ptr;
782 	SCC_ACCESS_INIT(port);
783 
784 	return (SCCread (SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0  : 1;
785 }
786 
787 
788 /* Comment taken from sx.c (2.4.0):
789    I haven't the foggiest why the decrement use count has to happen
790    here. The whole linux serial drivers stuff needs to be redesigned.
791    My guess is that this is a hack to minimize the impact of a bug
792    elsewhere. Thinking about it some more. (try it sometime) Try
793    running minicom on a serial port that is driven by a modularized
794    driver. Have the modem hangup. Then remove the driver module. Then
795    exit minicom.  I expect an "oops".  -- REW */
796 
scc_hungup(void * ptr)797 static void scc_hungup(void *ptr)
798 {
799 	scc_disable_tx_interrupts(ptr);
800 	scc_disable_rx_interrupts(ptr);
801 	MOD_DEC_USE_COUNT;
802 }
803 
804 
scc_close(void * ptr)805 static void scc_close(void *ptr)
806 {
807 	scc_disable_tx_interrupts(ptr);
808 	scc_disable_rx_interrupts(ptr);
809 	MOD_DEC_USE_COUNT;
810 }
811 
812 
813 /*---------------------------------------------------------------------------
814  * Internal support functions
815  *--------------------------------------------------------------------------*/
816 
scc_setsignals(struct scc_port * port,int dtr,int rts)817 static void scc_setsignals(struct scc_port *port, int dtr, int rts)
818 {
819 	unsigned long flags;
820 	unsigned char t;
821 	SCC_ACCESS_INIT(port);
822 
823 	save_flags(flags);
824 	cli();
825 	t = SCCread(TX_CTRL_REG);
826 	if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR);
827 	if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS);
828 	SCCwrite(TX_CTRL_REG, t);
829 	restore_flags(flags);
830 }
831 
832 
scc_send_xchar(struct tty_struct * tty,char ch)833 static void scc_send_xchar(struct tty_struct *tty, char ch)
834 {
835 	struct scc_port *port = (struct scc_port *)tty->driver_data;
836 
837 	port->x_char = ch;
838 	if (ch)
839 		scc_enable_tx_interrupts(port);
840 }
841 
842 
843 /*---------------------------------------------------------------------------
844  * Driver entrypoints referenced from above
845  *--------------------------------------------------------------------------*/
846 
scc_open(struct tty_struct * tty,struct file * filp)847 static int scc_open (struct tty_struct * tty, struct file * filp)
848 {
849 	int line = MINOR(tty->device) - SCC_MINOR_BASE;
850 	int retval;
851 	struct scc_port *port = &scc_ports[line];
852 	int i, channel = port->channel;
853 	unsigned long	flags;
854 	SCC_ACCESS_INIT(port);
855 #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_MVME147_SCC)
856 	static const struct {
857 		unsigned reg, val;
858 	} mvme_init_tab[] = {
859 		/* Values for MVME162 and MVME147 */
860 		/* no parity, 1 stop bit, async, 1:16 */
861 		{ AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 },
862 		/* parity error is special cond, ints disabled, no DMA */
863 		{ INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB },
864 		/* Rx 8 bits/char, no auto enable, Rx off */
865 		{ RX_CTRL_REG, RCR_CHSIZE_8 },
866 		/* DTR off, Tx 8 bits/char, RTS off, Tx off */
867 		{ TX_CTRL_REG, TCR_CHSIZE_8 },
868 		/* special features off */
869 		{ AUX2_CTRL_REG, 0 },
870 		{ CLK_CTRL_REG, CCR_RXCLK_BRG | CCR_TXCLK_BRG },
871 		{ DPLL_CTRL_REG, DCR_BRG_ENAB | DCR_BRG_USE_PCLK },
872 		/* Start Rx */
873 		{ RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 },
874 		/* Start Tx */
875 		{ TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 },
876 		/* Ext/Stat ints: DCD only */
877 		{ INT_CTRL_REG, ICR_ENAB_DCD_INT },
878 		/* Reset Ext/Stat ints */
879 		{ COMMAND_REG, CR_EXTSTAT_RESET },
880 		/* ...again */
881 		{ COMMAND_REG, CR_EXTSTAT_RESET },
882 	};
883 #endif
884 #if defined(CONFIG_BVME6000_SCC)
885 	static const struct {
886 		unsigned reg, val;
887 	} bvme_init_tab[] = {
888 		/* Values for BVME6000 */
889 		/* no parity, 1 stop bit, async, 1:16 */
890 		{ AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 },
891 		/* parity error is special cond, ints disabled, no DMA */
892 		{ INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB },
893 		/* Rx 8 bits/char, no auto enable, Rx off */
894 		{ RX_CTRL_REG, RCR_CHSIZE_8 },
895 		/* DTR off, Tx 8 bits/char, RTS off, Tx off */
896 		{ TX_CTRL_REG, TCR_CHSIZE_8 },
897 		/* special features off */
898 		{ AUX2_CTRL_REG, 0 },
899 		{ CLK_CTRL_REG, CCR_RTxC_XTAL | CCR_RXCLK_BRG | CCR_TXCLK_BRG },
900 		{ DPLL_CTRL_REG, DCR_BRG_ENAB },
901 		/* Start Rx */
902 		{ RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 },
903 		/* Start Tx */
904 		{ TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 },
905 		/* Ext/Stat ints: DCD only */
906 		{ INT_CTRL_REG, ICR_ENAB_DCD_INT },
907 		/* Reset Ext/Stat ints */
908 		{ COMMAND_REG, CR_EXTSTAT_RESET },
909 		/* ...again */
910 		{ COMMAND_REG, CR_EXTSTAT_RESET },
911 	};
912 #endif
913 	if (!(port->gs.flags & ASYNC_INITIALIZED)) {
914 		save_flags(flags);
915 		cli();
916 #if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC)
917 		if (MACH_IS_MVME147 || MACH_IS_MVME16x) {
918 			for (i=0; i<sizeof(mvme_init_tab)/sizeof(*mvme_init_tab); ++i)
919 				SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val);
920 		}
921 #endif
922 #if defined(CONFIG_BVME6000_SCC)
923 		if (MACH_IS_BVME6000) {
924 			for (i=0; i<sizeof(bvme_init_tab)/sizeof(*bvme_init_tab); ++i)
925 				SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val);
926 		}
927 #endif
928 
929 		/* remember status register for detection of DCD and CTS changes */
930 		scc_last_status_reg[channel] = SCCread(STATUS_REG);
931 
932 		port->c_dcd = 0;	/* Prevent initial 1->0 interrupt */
933 		scc_setsignals (port, 1,1);
934 		restore_flags(flags);
935 	}
936 
937 	tty->driver_data = port;
938 	port->gs.tty = tty;
939 	port->gs.count++;
940 	retval = gs_init_port(&port->gs);
941 	if (retval) {
942 		port->gs.count--;
943 		return retval;
944 	}
945 	port->gs.flags |= GS_ACTIVE;
946 	if (port->gs.count == 1) {
947 		MOD_INC_USE_COUNT;
948 	}
949 	retval = gs_block_til_ready(port, filp);
950 
951 	if (retval) {
952 		MOD_DEC_USE_COUNT;
953 		port->gs.count--;
954 		return retval;
955 	}
956 
957 	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
958 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
959 			*tty->termios = port->gs.normal_termios;
960 		else
961 			*tty->termios = port->gs.callout_termios;
962 		scc_set_real_termios (port);
963 	}
964 
965 	port->gs.session = current->session;
966 	port->gs.pgrp = current->pgrp;
967 	port->c_dcd = scc_get_CD (port);
968 
969 	scc_enable_rx_interrupts(port);
970 
971 	return 0;
972 }
973 
974 
scc_throttle(struct tty_struct * tty)975 static void scc_throttle (struct tty_struct * tty)
976 {
977 	struct scc_port *port = (struct scc_port *)tty->driver_data;
978 	unsigned long	flags;
979 	SCC_ACCESS_INIT(port);
980 
981 	if (tty->termios->c_cflag & CRTSCTS) {
982 		save_flags(flags);
983 		cli();
984 		SCCmod(TX_CTRL_REG, ~TCR_RTS, 0);
985 		restore_flags(flags);
986 	}
987 	if (I_IXOFF(tty))
988 		scc_send_xchar(tty, STOP_CHAR(tty));
989 }
990 
991 
scc_unthrottle(struct tty_struct * tty)992 static void scc_unthrottle (struct tty_struct * tty)
993 {
994 	struct scc_port *port = (struct scc_port *)tty->driver_data;
995 	unsigned long	flags;
996 	SCC_ACCESS_INIT(port);
997 
998 	if (tty->termios->c_cflag & CRTSCTS) {
999 		save_flags(flags);
1000 		cli();
1001 		SCCmod(TX_CTRL_REG, 0xff, TCR_RTS);
1002 		restore_flags(flags);
1003 	}
1004 	if (I_IXOFF(tty))
1005 		scc_send_xchar(tty, START_CHAR(tty));
1006 }
1007 
1008 
scc_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd,unsigned long arg)1009 static int scc_ioctl(struct tty_struct *tty, struct file *file,
1010 		     unsigned int cmd, unsigned long arg)
1011 {
1012 	return -ENOIOCTLCMD;
1013 }
1014 
1015 
scc_break_ctl(struct tty_struct * tty,int break_state)1016 static void scc_break_ctl(struct tty_struct *tty, int break_state)
1017 {
1018 	struct scc_port *port = (struct scc_port *)tty->driver_data;
1019 	unsigned long	flags;
1020 	SCC_ACCESS_INIT(port);
1021 
1022 	save_flags(flags);
1023 	cli();
1024 	SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK,
1025 			break_state ? TCR_SEND_BREAK : 0);
1026 	restore_flags(flags);
1027 }
1028 
1029 
1030 /*---------------------------------------------------------------------------
1031  * Serial console stuff...
1032  *--------------------------------------------------------------------------*/
1033 
1034 #define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0)
1035 
scc_ch_write(char ch)1036 static void scc_ch_write (char ch)
1037 {
1038 	volatile char *p = NULL;
1039 
1040 #ifdef CONFIG_MVME147_SCC
1041 	if (MACH_IS_MVME147)
1042 		p = (volatile char *)M147_SCC_A_ADDR;
1043 #endif
1044 #ifdef CONFIG_MVME162_SCC
1045 	if (MACH_IS_MVME16x)
1046 		p = (volatile char *)MVME_SCC_A_ADDR;
1047 #endif
1048 #ifdef CONFIG_BVME6000_SCC
1049 	if (MACH_IS_BVME6000)
1050 		p = (volatile char *)BVME_SCC_A_ADDR;
1051 #endif
1052 
1053 	do {
1054 		scc_delay();
1055 	}
1056 	while (!(*p & 4));
1057 	scc_delay();
1058 	*p = 8;
1059 	scc_delay();
1060 	*p = ch;
1061 }
1062 
1063 /* The console must be locked when we get here. */
1064 
scc_console_write(struct console * co,const char * str,unsigned count)1065 static void scc_console_write (struct console *co, const char *str, unsigned count)
1066 {
1067 	unsigned long	flags;
1068 
1069 	save_flags(flags);
1070 	cli();
1071 
1072 	while (count--)
1073 	{
1074 		if (*str == '\n')
1075 			scc_ch_write ('\r');
1076 		scc_ch_write (*str++);
1077 	}
1078 	restore_flags(flags);
1079 }
1080 
scc_console_device(struct console * c)1081 static kdev_t scc_console_device(struct console *c)
1082 {
1083 	return MKDEV(TTY_MAJOR, SCC_MINOR_BASE + c->index);
1084 }
1085 
1086 
scc_console_setup(struct console * co,char * options)1087 static int __init scc_console_setup(struct console *co, char *options)
1088 {
1089 	return 0;
1090 }
1091 
1092 
1093 static struct console sercons = {
1094 	name:		"ttyS",
1095 	write:		scc_console_write,
1096 	device:		scc_console_device,
1097 	setup:		scc_console_setup,
1098 	flags:		CON_PRINTBUFFER,
1099 	index:		-1,
1100 };
1101 
1102 
vme_scc_console_init(void)1103 void __init vme_scc_console_init(void)
1104 {
1105 	if (vme_brdtype == VME_TYPE_MVME147 ||
1106 			vme_brdtype == VME_TYPE_MVME162 ||
1107 			vme_brdtype == VME_TYPE_MVME172 ||
1108 			vme_brdtype == VME_TYPE_BVME4000 ||
1109 			vme_brdtype == VME_TYPE_BVME6000)
1110 		register_console(&sercons);
1111 }
1112 
1113