File: /usr/src/linux/drivers/char/vme_scc.c

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