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