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