Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / char / serial167.c
CommitLineData
1da177e4
LT
1/*
2 * linux/drivers/char/serial167.c
3 *
4 * Driver for MVME166/7 board serial ports, which are via a CD2401.
5 * Based very much on cyclades.c.
6 *
7 * MVME166/7 work by Richard Hirst [richard@sleepie.demon.co.uk]
8 *
9 * ==============================================================
10 *
11 * static char rcsid[] =
12 * "$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $";
13 *
14 * linux/kernel/cyclades.c
15 *
16 * Maintained by Marcio Saito (cyclades@netcom.com) and
17 * Randolph Bentson (bentson@grieg.seaslug.org)
18 *
19 * Much of the design and some of the code came from serial.c
20 * which was copyright (C) 1991, 1992 Linus Torvalds. It was
21 * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
22 * and then fixed as suggested by Michael K. Johnson 12/12/92.
23 *
24 * This version does not support shared irq's.
25 *
26 * $Log: cyclades.c,v $
27 * Revision 1.36.1.4 1995/03/29 06:14:14 bentson
28 * disambiguate between Cyclom-16Y and Cyclom-32Ye;
29 *
30 * Changes:
31 *
32 * 200 lines of changes record removed - RGH 11-10-95, starting work on
33 * converting this to drive serial ports on mvme166 (cd2401).
34 *
35 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/08/25
36 * - get rid of verify_area
37 * - use get_user to access memory from userspace in set_threshold,
38 * set_default_threshold and set_timeout
39 * - don't use the panic function in serial167_init
40 * - do resource release on failure on serial167_init
41 * - include missing restore_flags in mvme167_serial_console_setup
42 *
43 * Kars de Jong <jongk@linux-m68k.org> - 2004/09/06
44 * - replace bottom half handler with task queue handler
45 */
46
1da177e4
LT
47#include <linux/errno.h>
48#include <linux/signal.h>
49#include <linux/sched.h>
50#include <linux/timer.h>
51#include <linux/tty.h>
52#include <linux/interrupt.h>
53#include <linux/serial.h>
54#include <linux/serialP.h>
405f5571 55#include <linux/smp_lock.h>
1da177e4
LT
56#include <linux/string.h>
57#include <linux/fcntl.h>
58#include <linux/ptrace.h>
59#include <linux/serial167.h>
60#include <linux/delay.h>
61#include <linux/major.h>
62#include <linux/mm.h>
63#include <linux/console.h>
64#include <linux/module.h>
65#include <linux/bitops.h>
81e859ac 66#include <linux/tty_flip.h>
5a0e3ad6 67#include <linux/gfp.h>
1da177e4
LT
68
69#include <asm/system.h>
70#include <asm/io.h>
71#include <asm/mvme16xhw.h>
72#include <asm/bootinfo.h>
73#include <asm/setup.h>
74
75#include <linux/types.h>
76#include <linux/kernel.h>
77
78#include <asm/uaccess.h>
79#include <linux/init.h>
80
81#define SERIAL_PARANOIA_CHECK
82#undef SERIAL_DEBUG_OPEN
83#undef SERIAL_DEBUG_THROTTLE
84#undef SERIAL_DEBUG_OTHER
85#undef SERIAL_DEBUG_IO
86#undef SERIAL_DEBUG_COUNT
87#undef SERIAL_DEBUG_DTR
88#undef CYCLOM_16Y_HACK
89#define CYCLOM_ENABLE_MONITORING
90
91#define WAKEUP_CHARS 256
92
93#define STD_COM_FLAGS (0)
94
1da177e4
LT
95static struct tty_driver *cy_serial_driver;
96extern int serial_console;
97static struct cyclades_port *serial_console_info = NULL;
98static unsigned int serial_console_cflag = 0;
99u_char initial_console_speed;
100
101/* Base address of cd2401 chip on mvme166/7 */
102
103#define BASE_ADDR (0xfff45000)
104#define pcc2chip ((volatile u_char *)0xfff42000)
105#define PccSCCMICR 0x1d
106#define PccSCCTICR 0x1e
107#define PccSCCRICR 0x1f
108#define PccTPIACKR 0x25
109#define PccRPIACKR 0x27
110#define PccIMLR 0x3f
111
112/* This is the per-port data structure */
113struct cyclades_port cy_port[] = {
44bafdf3
JS
114 /* CARD# */
115 {-1}, /* ttyS0 */
116 {-1}, /* ttyS1 */
117 {-1}, /* ttyS2 */
118 {-1}, /* ttyS3 */
1da177e4 119};
44bafdf3 120
fe971071 121#define NR_PORTS ARRAY_SIZE(cy_port)
1da177e4 122
1da177e4
LT
123/*
124 * This is used to look up the divisor speeds and the timeouts
125 * We're normally limited to 15 distinct baud rates. The extra
126 * are accessed via settings in info->flags.
127 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
128 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
129 * HI VHI
130 */
131static int baud_table[] = {
44bafdf3
JS
132 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
133 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
134 0
135};
1da177e4
LT
136
137#if 0
44bafdf3
JS
138static char baud_co[] = { /* 25 MHz clock option table */
139 /* value => 00 01 02 03 04 */
140 /* divide by 8 32 128 512 2048 */
141 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
142 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
143};
1da177e4 144
44bafdf3
JS
145static char baud_bpr[] = { /* 25 MHz baud rate period table */
146 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
147 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
148};
1da177e4
LT
149#endif
150
151/* I think 166 brd clocks 2401 at 20MHz.... */
152
153/* These values are written directly to tcor, and >> 5 for writing to rcor */
44bafdf3
JS
154static u_char baud_co[] = { /* 20 MHz clock option table */
155 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40,
156 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
157};
1da177e4
LT
158
159/* These values written directly to tbpr/rbpr */
44bafdf3
JS
160static u_char baud_bpr[] = { /* 20 MHz baud rate period table */
161 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81,
162 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10
163};
1da177e4 164
44bafdf3
JS
165static u_char baud_cor4[] = { /* receive threshold */
166 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
167 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07
168};
1da177e4
LT
169
170static void shutdown(struct cyclades_port *);
44bafdf3 171static int startup(struct cyclades_port *);
1da177e4
LT
172static void cy_throttle(struct tty_struct *);
173static void cy_unthrottle(struct tty_struct *);
174static void config_setup(struct cyclades_port *);
1da177e4
LT
175#ifdef CYCLOM_SHOW_STATUS
176static void show_status(int);
177#endif
178
1da177e4
LT
179/*
180 * I have my own version of udelay(), as it is needed when initialising
181 * the chip, before the delay loop has been calibrated. Should probably
182 * reference one of the vmechip2 or pccchip2 counter for an accurate
183 * delay, but this wild guess will do for now.
184 */
185
44bafdf3 186void my_udelay(long us)
1da177e4
LT
187{
188 u_char x;
189 volatile u_char *p = &x;
190 int i;
191
192 while (us--)
193 for (i = 100; i; i--)
194 x |= *p;
195}
196
44bafdf3
JS
197static inline int serial_paranoia_check(struct cyclades_port *info, char *name,
198 const char *routine)
1da177e4
LT
199{
200#ifdef SERIAL_PARANOIA_CHECK
44bafdf3
JS
201 if (!info) {
202 printk("Warning: null cyclades_port for (%s) in %s\n", name,
203 routine);
204 return 1;
205 }
206
f23fc156 207 if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) {
44bafdf3
JS
208 printk("Warning: cyclades_port out of range for (%s) in %s\n",
209 name, routine);
210 return 1;
211 }
212
213 if (info->magic != CYCLADES_MAGIC) {
214 printk("Warning: bad magic number for serial struct (%s) in "
215 "%s\n", name, routine);
216 return 1;
217 }
1da177e4
LT
218#endif
219 return 0;
44bafdf3 220} /* serial_paranoia_check */
1da177e4
LT
221
222#if 0
223/* The following diagnostic routines allow the driver to spew
224 information on the screen, even (especially!) during interrupts.
225 */
44bafdf3
JS
226void SP(char *data)
227{
228 unsigned long flags;
229 local_irq_save(flags);
353f6dd2 230 printk(KERN_EMERG "%s", data);
44bafdf3 231 local_irq_restore(flags);
1da177e4 232}
44bafdf3 233
1da177e4 234char scrn[2];
44bafdf3
JS
235void CP(char data)
236{
237 unsigned long flags;
238 local_irq_save(flags);
239 scrn[0] = data;
353f6dd2 240 printk(KERN_EMERG "%c", scrn);
44bafdf3
JS
241 local_irq_restore(flags);
242} /* CP */
1da177e4 243
44bafdf3
JS
244void CP1(int data)
245{
246 (data < 10) ? CP(data + '0') : CP(data + 'A' - 10);
247} /* CP1 */
248void CP2(int data)
249{
250 CP1((data >> 4) & 0x0f);
251 CP1(data & 0x0f);
252} /* CP2 */
253void CP4(int data)
254{
255 CP2((data >> 8) & 0xff);
256 CP2(data & 0xff);
257} /* CP4 */
258void CP8(long data)
259{
260 CP4((data >> 16) & 0xffff);
261 CP4(data & 0xffff);
262} /* CP8 */
1da177e4
LT
263#endif
264
265/* This routine waits up to 1000 micro-seconds for the previous
266 command to the Cirrus chip to complete and then issues the
267 new command. An error is returned if the previous command
268 didn't finish within the time limit.
269 */
44bafdf3 270u_short write_cy_cmd(volatile u_char * base_addr, u_char cmd)
1da177e4 271{
44bafdf3
JS
272 unsigned long flags;
273 volatile int i;
1da177e4 274
44bafdf3 275 local_irq_save(flags);
1da177e4 276 /* Check to see that the previous command has completed */
44bafdf3
JS
277 for (i = 0; i < 100; i++) {
278 if (base_addr[CyCCR] == 0) {
279 break;
280 }
281 my_udelay(10L);
1da177e4
LT
282 }
283 /* if the CCR never cleared, the previous command
44bafdf3
JS
284 didn't finish within the "reasonable time" */
285 if (i == 10) {
286 local_irq_restore(flags);
287 return (-1);
1da177e4
LT
288 }
289
290 /* Issue the new command */
291 base_addr[CyCCR] = cmd;
44bafdf3
JS
292 local_irq_restore(flags);
293 return (0);
294} /* write_cy_cmd */
1da177e4
LT
295
296/* cy_start and cy_stop provide software output flow control as a
297 function of XON/XOFF, software CTS, and other such stuff. */
298
44bafdf3 299static void cy_stop(struct tty_struct *tty)
1da177e4 300{
c9f19e96 301 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
302 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
303 int channel;
304 unsigned long flags;
1da177e4
LT
305
306#ifdef SERIAL_DEBUG_OTHER
44bafdf3 307 printk("cy_stop %s\n", tty->name); /* */
1da177e4
LT
308#endif
309
44bafdf3
JS
310 if (serial_paranoia_check(info, tty->name, "cy_stop"))
311 return;
1da177e4 312
44bafdf3 313 channel = info->line;
1da177e4 314
44bafdf3
JS
315 local_irq_save(flags);
316 base_addr[CyCAR] = (u_char) (channel); /* index channel */
317 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
318 local_irq_restore(flags);
319} /* cy_stop */
1da177e4 320
44bafdf3 321static void cy_start(struct tty_struct *tty)
1da177e4 322{
c9f19e96 323 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
324 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
325 int channel;
326 unsigned long flags;
1da177e4
LT
327
328#ifdef SERIAL_DEBUG_OTHER
44bafdf3 329 printk("cy_start %s\n", tty->name); /* */
1da177e4
LT
330#endif
331
44bafdf3
JS
332 if (serial_paranoia_check(info, tty->name, "cy_start"))
333 return;
1da177e4 334
44bafdf3 335 channel = info->line;
1da177e4 336
44bafdf3
JS
337 local_irq_save(flags);
338 base_addr[CyCAR] = (u_char) (channel);
339 base_addr[CyIER] |= CyTxMpty;
340 local_irq_restore(flags);
341} /* cy_start */
1da177e4 342
1da177e4
LT
343/* The real interrupt service routines are called
344 whenever the card wants its hand held--chars
345 received, out buffer empty, modem change, etc.
346 */
44bafdf3 347static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id)
1da177e4 348{
44bafdf3
JS
349 struct tty_struct *tty;
350 struct cyclades_port *info;
351 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
352 unsigned char err, rfoc;
353 int channel;
354 char data;
355
356 /* determine the channel and change to that context */
357 channel = (u_short) (base_addr[CyLICR] >> 2);
358 info = &cy_port[channel];
359 info->last_active = jiffies;
360
361 if ((err = base_addr[CyRISR]) & CyTIMEOUT) {
362 /* This is a receive timeout interrupt, ignore it */
363 base_addr[CyREOIR] = CyNOTRANS;
364 return IRQ_HANDLED;
365 }
1da177e4 366
44bafdf3
JS
367 /* Read a byte of data if there is any - assume the error
368 * is associated with this character */
1da177e4 369
44bafdf3
JS
370 if ((rfoc = base_addr[CyRFOC]) != 0)
371 data = base_addr[CyRDR];
372 else
373 data = 0;
374
375 /* if there is nowhere to put the data, discard it */
376 if (info->tty == 0) {
377 base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
378 return IRQ_HANDLED;
379 } else { /* there is an open port for this data */
380 tty = info->tty;
381 if (err & info->ignore_status_mask) {
382 base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
383 return IRQ_HANDLED;
384 }
385 if (tty_buffer_request_room(tty, 1) != 0) {
386 if (err & info->read_status_mask) {
387 if (err & CyBREAK) {
388 tty_insert_flip_char(tty, data,
389 TTY_BREAK);
390 if (info->flags & ASYNC_SAK) {
391 do_SAK(tty);
392 }
393 } else if (err & CyFRAME) {
394 tty_insert_flip_char(tty, data,
395 TTY_FRAME);
396 } else if (err & CyPARITY) {
397 tty_insert_flip_char(tty, data,
398 TTY_PARITY);
399 } else if (err & CyOVERRUN) {
400 tty_insert_flip_char(tty, 0,
401 TTY_OVERRUN);
402 /*
403 If the flip buffer itself is
c4f01240 404 overflowing, we still lose
44bafdf3
JS
405 the next incoming character.
406 */
407 if (tty_buffer_request_room(tty, 1) !=
408 0) {
409 tty_insert_flip_char(tty, data,
410 TTY_FRAME);
411 }
412 /* These two conditions may imply */
413 /* a normal read should be done. */
414 /* else if(data & CyTIMEOUT) */
415 /* else if(data & CySPECHAR) */
416 } else {
417 tty_insert_flip_char(tty, 0,
418 TTY_NORMAL);
419 }
420 } else {
421 tty_insert_flip_char(tty, data, TTY_NORMAL);
422 }
423 } else {
424 /* there was a software buffer overrun
425 and nothing could be done about it!!! */
426 }
427 }
428 tty_schedule_flip(tty);
429 /* end of service */
1da177e4
LT
430 base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
431 return IRQ_HANDLED;
44bafdf3
JS
432} /* cy_rxerr_interrupt */
433
434static irqreturn_t cd2401_modem_interrupt(int irq, void *dev_id)
1da177e4 435{
44bafdf3
JS
436 struct cyclades_port *info;
437 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
438 int channel;
439 int mdm_change;
440 int mdm_status;
441
442 /* determine the channel and change to that context */
443 channel = (u_short) (base_addr[CyLICR] >> 2);
444 info = &cy_port[channel];
445 info->last_active = jiffies;
446
447 mdm_change = base_addr[CyMISR];
448 mdm_status = base_addr[CyMSVR1];
449
450 if (info->tty == 0) { /* nowhere to put the data, ignore it */
451 ;
452 } else {
453 if ((mdm_change & CyDCD)
454 && (info->flags & ASYNC_CHECK_CD)) {
455 if (mdm_status & CyDCD) {
1da177e4 456/* CP('!'); */
3099bbc5 457 wake_up_interruptible(&info->open_wait);
44bafdf3 458 } else {
1da177e4 459/* CP('@'); */
3099bbc5
JS
460 tty_hangup(info->tty);
461 wake_up_interruptible(&info->open_wait);
462 info->flags &= ~ASYNC_NORMAL_ACTIVE;
44bafdf3 463 }
1da177e4 464 }
44bafdf3
JS
465 if ((mdm_change & CyCTS)
466 && (info->flags & ASYNC_CTS_FLOW)) {
467 if (info->tty->stopped) {
468 if (mdm_status & CyCTS) {
469 /* !!! cy_start isn't used because... */
470 info->tty->stopped = 0;
471 base_addr[CyIER] |= CyTxMpty;
3099bbc5 472 tty_wakeup(info->tty);
44bafdf3
JS
473 }
474 } else {
475 if (!(mdm_status & CyCTS)) {
476 /* !!! cy_stop isn't used because... */
477 info->tty->stopped = 1;
478 base_addr[CyIER] &=
479 ~(CyTxMpty | CyTxRdy);
480 }
481 }
482 }
483 if (mdm_status & CyDSR) {
1da177e4 484 }
1da177e4 485 }
44bafdf3
JS
486 base_addr[CyMEOIR] = 0;
487 return IRQ_HANDLED;
488} /* cy_modem_interrupt */
1da177e4 489
44bafdf3 490static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id)
1da177e4 491{
44bafdf3
JS
492 struct cyclades_port *info;
493 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
494 int channel;
495 int char_count, saved_cnt;
496 int outch;
1da177e4 497
44bafdf3
JS
498 /* determine the channel and change to that context */
499 channel = (u_short) (base_addr[CyLICR] >> 2);
1da177e4 500
44bafdf3
JS
501 /* validate the port number (as configured and open) */
502 if ((channel < 0) || (NR_PORTS <= channel)) {
503 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
504 base_addr[CyTEOIR] = CyNOTRANS;
505 return IRQ_HANDLED;
506 }
f23fc156 507 info = &cy_port[channel];
44bafdf3
JS
508 info->last_active = jiffies;
509 if (info->tty == 0) {
510 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
44bafdf3
JS
511 base_addr[CyTEOIR] = CyNOTRANS;
512 return IRQ_HANDLED;
513 }
514
515 /* load the on-chip space available for outbound data */
516 saved_cnt = char_count = base_addr[CyTFTC];
517
518 if (info->x_char) { /* send special char */
519 outch = info->x_char;
1da177e4 520 base_addr[CyTDR] = outch;
1da177e4 521 char_count--;
44bafdf3 522 info->x_char = 0;
1da177e4 523 }
1da177e4 524
44bafdf3
JS
525 if (info->x_break) {
526 /* The Cirrus chip requires the "Embedded Transmit
527 Commands" of start break, delay, and end break
528 sequences to be sent. The duration of the
529 break is given in TICs, which runs at HZ
530 (typically 100) and the PPR runs at 200 Hz,
531 so the delay is duration * 200/HZ, and thus a
532 break can run from 1/100 sec to about 5/4 sec.
533 Need to check these values - RGH 141095.
534 */
535 base_addr[CyTDR] = 0; /* start break */
536 base_addr[CyTDR] = 0x81;
537 base_addr[CyTDR] = 0; /* delay a bit */
538 base_addr[CyTDR] = 0x82;
539 base_addr[CyTDR] = info->x_break * 200 / HZ;
540 base_addr[CyTDR] = 0; /* terminate break */
541 base_addr[CyTDR] = 0x83;
542 char_count -= 7;
543 info->x_break = 0;
544 }
545
546 while (char_count > 0) {
547 if (!info->xmit_cnt) {
548 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
549 break;
550 }
551 if (info->xmit_buf == 0) {
552 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
553 break;
554 }
555 if (info->tty->stopped || info->tty->hw_stopped) {
556 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
557 break;
558 }
559 /* Because the Embedded Transmit Commands have been
560 enabled, we must check to see if the escape
561 character, NULL, is being sent. If it is, we
562 must ensure that there is room for it to be
563 doubled in the output stream. Therefore we
564 no longer advance the pointer when the character
565 is fetched, but rather wait until after the check
566 for a NULL output character. (This is necessary
567 because there may not be room for the two chars
568 needed to send a NULL.
569 */
570 outch = info->xmit_buf[info->xmit_tail];
571 if (outch) {
572 info->xmit_cnt--;
573 info->xmit_tail = (info->xmit_tail + 1)
574 & (PAGE_SIZE - 1);
575 base_addr[CyTDR] = outch;
576 char_count--;
577 } else {
578 if (char_count > 1) {
579 info->xmit_cnt--;
580 info->xmit_tail = (info->xmit_tail + 1)
581 & (PAGE_SIZE - 1);
582 base_addr[CyTDR] = outch;
583 base_addr[CyTDR] = 0;
584 char_count--;
585 char_count--;
586 } else {
587 break;
588 }
589 }
590 }
591
3099bbc5
JS
592 if (info->xmit_cnt < WAKEUP_CHARS)
593 tty_wakeup(info->tty);
594
44bafdf3
JS
595 base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS;
596 return IRQ_HANDLED;
597} /* cy_tx_interrupt */
1da177e4 598
44bafdf3 599static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id)
1da177e4 600{
44bafdf3
JS
601 struct tty_struct *tty;
602 struct cyclades_port *info;
603 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
604 int channel;
605 char data;
606 int char_count;
607 int save_cnt;
44bafdf3
JS
608
609 /* determine the channel and change to that context */
610 channel = (u_short) (base_addr[CyLICR] >> 2);
611 info = &cy_port[channel];
612 info->last_active = jiffies;
613 save_cnt = char_count = base_addr[CyRFOC];
1da177e4 614
44bafdf3
JS
615 /* if there is nowhere to put the data, discard it */
616 if (info->tty == 0) {
617 while (char_count--) {
618 data = base_addr[CyRDR];
619 }
620 } else { /* there is an open port for this data */
621 tty = info->tty;
622 /* load # characters available from the chip */
1da177e4
LT
623
624#ifdef CYCLOM_ENABLE_MONITORING
44bafdf3
JS
625 ++info->mon.int_count;
626 info->mon.char_count += char_count;
627 if (char_count > info->mon.char_max)
628 info->mon.char_max = char_count;
629 info->mon.char_last = char_count;
630#endif
4165fe4e 631 while (char_count--) {
44bafdf3
JS
632 data = base_addr[CyRDR];
633 tty_insert_flip_char(tty, data, TTY_NORMAL);
1da177e4 634#ifdef CYCLOM_16Y_HACK
44bafdf3 635 udelay(10L);
1da177e4 636#endif
44bafdf3
JS
637 }
638 tty_schedule_flip(tty);
639 }
640 /* end of service */
641 base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
642 return IRQ_HANDLED;
643} /* cy_rx_interrupt */
1da177e4 644
1da177e4
LT
645/* This is called whenever a port becomes active;
646 interrupts are enabled and DTR & RTS are turned on.
647 */
44bafdf3 648static int startup(struct cyclades_port *info)
1da177e4 649{
44bafdf3
JS
650 unsigned long flags;
651 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
652 int channel;
1da177e4 653
44bafdf3
JS
654 if (info->flags & ASYNC_INITIALIZED) {
655 return 0;
656 }
1da177e4 657
44bafdf3
JS
658 if (!info->type) {
659 if (info->tty) {
660 set_bit(TTY_IO_ERROR, &info->tty->flags);
661 }
662 return 0;
1da177e4 663 }
44bafdf3
JS
664 if (!info->xmit_buf) {
665 info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
666 if (!info->xmit_buf) {
667 return -ENOMEM;
668 }
1da177e4 669 }
1da177e4 670
44bafdf3 671 config_setup(info);
1da177e4 672
44bafdf3 673 channel = info->line;
1da177e4
LT
674
675#ifdef SERIAL_DEBUG_OPEN
44bafdf3 676 printk("startup channel %d\n", channel);
1da177e4
LT
677#endif
678
44bafdf3
JS
679 local_irq_save(flags);
680 base_addr[CyCAR] = (u_char) channel;
681 write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR);
1da177e4 682
44bafdf3 683 base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */
1da177e4
LT
684 base_addr[CyMSVR1] = CyRTS;
685/* CP('S');CP('1'); */
686 base_addr[CyMSVR2] = CyDTR;
687
688#ifdef SERIAL_DEBUG_DTR
44bafdf3
JS
689 printk("cyc: %d: raising DTR\n", __LINE__);
690 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
691 base_addr[CyMSVR2]);
1da177e4
LT
692#endif
693
694 base_addr[CyIER] |= CyRxData;
695 info->flags |= ASYNC_INITIALIZED;
696
44bafdf3
JS
697 if (info->tty) {
698 clear_bit(TTY_IO_ERROR, &info->tty->flags);
1da177e4
LT
699 }
700 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
701
44bafdf3 702 local_irq_restore(flags);
1da177e4
LT
703
704#ifdef SERIAL_DEBUG_OPEN
44bafdf3 705 printk(" done\n");
1da177e4 706#endif
44bafdf3
JS
707 return 0;
708} /* startup */
1da177e4 709
44bafdf3 710void start_xmit(struct cyclades_port *info)
1da177e4 711{
44bafdf3
JS
712 unsigned long flags;
713 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
714 int channel;
1da177e4 715
44bafdf3
JS
716 channel = info->line;
717 local_irq_save(flags);
1da177e4
LT
718 base_addr[CyCAR] = channel;
719 base_addr[CyIER] |= CyTxMpty;
44bafdf3
JS
720 local_irq_restore(flags);
721} /* start_xmit */
1da177e4
LT
722
723/*
724 * This routine shuts down a serial port; interrupts are disabled,
725 * and DTR is dropped if the hangup on close termio flag is on.
726 */
44bafdf3 727static void shutdown(struct cyclades_port *info)
1da177e4 728{
44bafdf3
JS
729 unsigned long flags;
730 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
731 int channel;
1da177e4 732
44bafdf3 733 if (!(info->flags & ASYNC_INITIALIZED)) {
1da177e4 734/* CP('$'); */
44bafdf3
JS
735 return;
736 }
1da177e4 737
44bafdf3 738 channel = info->line;
1da177e4
LT
739
740#ifdef SERIAL_DEBUG_OPEN
44bafdf3 741 printk("shutdown channel %d\n", channel);
1da177e4
LT
742#endif
743
44bafdf3
JS
744 /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE
745 SENT BEFORE DROPPING THE LINE !!! (Perhaps
746 set some flag that is read when XMTY happens.)
747 Other choices are to delay some fixed interval
748 or schedule some later processing.
749 */
750 local_irq_save(flags);
751 if (info->xmit_buf) {
752 free_page((unsigned long)info->xmit_buf);
753 info->xmit_buf = NULL;
1da177e4
LT
754 }
755
44bafdf3 756 base_addr[CyCAR] = (u_char) channel;
1da177e4 757 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
44bafdf3 758 base_addr[CyMSVR1] = 0;
1da177e4 759/* CP('C');CP('1'); */
44bafdf3 760 base_addr[CyMSVR2] = 0;
1da177e4 761#ifdef SERIAL_DEBUG_DTR
44bafdf3
JS
762 printk("cyc: %d: dropping DTR\n", __LINE__);
763 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
764 base_addr[CyMSVR2]);
1da177e4 765#endif
44bafdf3
JS
766 }
767 write_cy_cmd(base_addr, CyDIS_RCVR);
768 /* it may be appropriate to clear _XMIT at
769 some later date (after testing)!!! */
1da177e4 770
44bafdf3
JS
771 if (info->tty) {
772 set_bit(TTY_IO_ERROR, &info->tty->flags);
1da177e4
LT
773 }
774 info->flags &= ~ASYNC_INITIALIZED;
44bafdf3 775 local_irq_restore(flags);
1da177e4
LT
776
777#ifdef SERIAL_DEBUG_OPEN
44bafdf3 778 printk(" done\n");
1da177e4 779#endif
44bafdf3 780} /* shutdown */
1da177e4
LT
781
782/*
783 * This routine finds or computes the various line characteristics.
784 */
44bafdf3 785static void config_setup(struct cyclades_port *info)
1da177e4 786{
44bafdf3
JS
787 unsigned long flags;
788 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
789 int channel;
790 unsigned cflag;
791 int i;
792 unsigned char ti, need_init_chan = 0;
793
794 if (!info->tty || !info->tty->termios) {
795 return;
796 }
797 if (info->line == -1) {
798 return;
799 }
800 cflag = info->tty->termios->c_cflag;
801
802 /* baud rate */
803 i = cflag & CBAUD;
1da177e4
LT
804#ifdef CBAUDEX
805/* Starting with kernel 1.1.65, there is direct support for
806 higher baud rates. The following code supports those
807 changes. The conditional aspect allows this driver to be
808 used for earlier as well as later kernel versions. (The
809 mapping is slightly different from serial.c because there
810 is still the possibility of supporting 75 kbit/sec with
811 the Cyclades board.)
812 */
44bafdf3
JS
813 if (i & CBAUDEX) {
814 if (i == B57600)
815 i = 16;
816 else if (i == B115200)
817 i = 18;
1da177e4 818#ifdef B78600
44bafdf3
JS
819 else if (i == B78600)
820 i = 17;
1da177e4 821#endif
44bafdf3
JS
822 else
823 info->tty->termios->c_cflag &= ~CBAUDEX;
824 }
825#endif
826 if (i == 15) {
827 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
828 i += 1;
829 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
830 i += 3;
831 }
832 /* Don't ever change the speed of the console port. It will
833 * run at the speed specified in bootinfo, or at 19.2K */
834 /* Actually, it should run at whatever speed 166Bug was using */
835 /* Note info->timeout isn't used at present */
836 if (info != serial_console_info) {
837 info->tbpr = baud_bpr[i]; /* Tx BPR */
838 info->tco = baud_co[i]; /* Tx CO */
839 info->rbpr = baud_bpr[i]; /* Rx BPR */
840 info->rco = baud_co[i] >> 5; /* Rx CO */
841 if (baud_table[i] == 134) {
842 info->timeout =
843 (info->xmit_fifo_size * HZ * 30 / 269) + 2;
844 /* get it right for 134.5 baud */
845 } else if (baud_table[i]) {
846 info->timeout =
847 (info->xmit_fifo_size * HZ * 15 / baud_table[i]) +
848 2;
849 /* this needs to be propagated into the card info */
850 } else {
851 info->timeout = 0;
852 }
853 }
854 /* By tradition (is it a standard?) a baud rate of zero
855 implies the line should be/has been closed. A bit
856 later in this routine such a test is performed. */
857
858 /* byte size and parity */
859 info->cor7 = 0;
860 info->cor6 = 0;
861 info->cor5 = 0;
862 info->cor4 = (info->default_threshold ? info->default_threshold : baud_cor4[i]); /* receive threshold */
863 /* Following two lines added 101295, RGH. */
864 /* It is obviously wrong to access CyCORx, and not info->corx here,
865 * try and remember to fix it later! */
866 channel = info->line;
867 base_addr[CyCAR] = (u_char) channel;
868 if (C_CLOCAL(info->tty)) {
869 if (base_addr[CyIER] & CyMdmCh)
870 base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */
871 /* ignore 1->0 modem transitions */
872 if (base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD))
873 base_addr[CyCOR4] &= ~(CyDSR | CyCTS | CyDCD);
874 /* ignore 0->1 modem transitions */
875 if (base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD))
876 base_addr[CyCOR5] &= ~(CyDSR | CyCTS | CyDCD);
1da177e4 877 } else {
44bafdf3
JS
878 if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh)
879 base_addr[CyIER] |= CyMdmCh; /* with modem intr */
880 /* act on 1->0 modem transitions */
881 if ((base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) !=
882 (CyDSR | CyCTS | CyDCD))
883 base_addr[CyCOR4] |= CyDSR | CyCTS | CyDCD;
884 /* act on 0->1 modem transitions */
885 if ((base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) !=
886 (CyDSR | CyCTS | CyDCD))
887 base_addr[CyCOR5] |= CyDSR | CyCTS | CyDCD;
888 }
889 info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP;
890 info->cor2 = CyETC;
891 switch (cflag & CSIZE) {
892 case CS5:
893 info->cor1 = Cy_5_BITS;
894 break;
895 case CS6:
896 info->cor1 = Cy_6_BITS;
897 break;
898 case CS7:
899 info->cor1 = Cy_7_BITS;
900 break;
901 case CS8:
902 info->cor1 = Cy_8_BITS;
903 break;
904 }
905 if (cflag & PARENB) {
906 if (cflag & PARODD) {
907 info->cor1 |= CyPARITY_O;
908 } else {
909 info->cor1 |= CyPARITY_E;
910 }
911 } else {
912 info->cor1 |= CyPARITY_NONE;
913 }
914
915 /* CTS flow control flag */
1da177e4 916#if 0
44bafdf3
JS
917 /* Don't complcate matters for now! RGH 141095 */
918 if (cflag & CRTSCTS) {
919 info->flags |= ASYNC_CTS_FLOW;
920 info->cor2 |= CyCtsAE;
921 } else {
922 info->flags &= ~ASYNC_CTS_FLOW;
923 info->cor2 &= ~CyCtsAE;
924 }
925#endif
926 if (cflag & CLOCAL)
927 info->flags &= ~ASYNC_CHECK_CD;
928 else
929 info->flags |= ASYNC_CHECK_CD;
1da177e4
LT
930
931 /***********************************************
932 The hardware option, CyRtsAO, presents RTS when
933 the chip has characters to send. Since most modems
934 use RTS as reverse (inbound) flow control, this
935 option is not used. If inbound flow control is
936 necessary, DTR can be programmed to provide the
937 appropriate signals for use with a non-standard
938 cable. Contact Marcio Saito for details.
939 ***********************************************/
940
44bafdf3 941 channel = info->line;
1da177e4 942
44bafdf3
JS
943 local_irq_save(flags);
944 base_addr[CyCAR] = (u_char) channel;
1da177e4
LT
945
946 /* CyCMR set once only in mvme167_init_serial() */
947 if (base_addr[CyLICR] != channel << 2)
44bafdf3 948 base_addr[CyLICR] = channel << 2;
1da177e4 949 if (base_addr[CyLIVR] != 0x5c)
44bafdf3 950 base_addr[CyLIVR] = 0x5c;
1da177e4 951
44bafdf3 952 /* tx and rx baud rate */
1da177e4
LT
953
954 if (base_addr[CyCOR1] != info->cor1)
44bafdf3 955 need_init_chan = 1;
1da177e4 956 if (base_addr[CyTCOR] != info->tco)
44bafdf3 957 base_addr[CyTCOR] = info->tco;
1da177e4 958 if (base_addr[CyTBPR] != info->tbpr)
44bafdf3 959 base_addr[CyTBPR] = info->tbpr;
1da177e4 960 if (base_addr[CyRCOR] != info->rco)
44bafdf3 961 base_addr[CyRCOR] = info->rco;
1da177e4 962 if (base_addr[CyRBPR] != info->rbpr)
44bafdf3 963 base_addr[CyRBPR] = info->rbpr;
1da177e4
LT
964
965 /* set line characteristics according configuration */
966
967 if (base_addr[CySCHR1] != START_CHAR(info->tty))
44bafdf3 968 base_addr[CySCHR1] = START_CHAR(info->tty);
1da177e4 969 if (base_addr[CySCHR2] != STOP_CHAR(info->tty))
44bafdf3 970 base_addr[CySCHR2] = STOP_CHAR(info->tty);
1da177e4 971 if (base_addr[CySCRL] != START_CHAR(info->tty))
44bafdf3 972 base_addr[CySCRL] = START_CHAR(info->tty);
1da177e4 973 if (base_addr[CySCRH] != START_CHAR(info->tty))
44bafdf3 974 base_addr[CySCRH] = START_CHAR(info->tty);
1da177e4 975 if (base_addr[CyCOR1] != info->cor1)
44bafdf3 976 base_addr[CyCOR1] = info->cor1;
1da177e4 977 if (base_addr[CyCOR2] != info->cor2)
44bafdf3 978 base_addr[CyCOR2] = info->cor2;
1da177e4 979 if (base_addr[CyCOR3] != info->cor3)
44bafdf3 980 base_addr[CyCOR3] = info->cor3;
1da177e4 981 if (base_addr[CyCOR4] != info->cor4)
44bafdf3 982 base_addr[CyCOR4] = info->cor4;
1da177e4 983 if (base_addr[CyCOR5] != info->cor5)
44bafdf3 984 base_addr[CyCOR5] = info->cor5;
1da177e4 985 if (base_addr[CyCOR6] != info->cor6)
44bafdf3 986 base_addr[CyCOR6] = info->cor6;
1da177e4 987 if (base_addr[CyCOR7] != info->cor7)
44bafdf3 988 base_addr[CyCOR7] = info->cor7;
1da177e4
LT
989
990 if (need_init_chan)
44bafdf3 991 write_cy_cmd(base_addr, CyINIT_CHAN);
1da177e4 992
44bafdf3 993 base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */
1da177e4
LT
994
995 /* 2ms default rx timeout */
996 ti = info->default_timeout ? info->default_timeout : 0x02;
997 if (base_addr[CyRTPRL] != ti)
44bafdf3 998 base_addr[CyRTPRL] = ti;
1da177e4 999 if (base_addr[CyRTPRH] != 0)
44bafdf3 1000 base_addr[CyRTPRH] = 0;
1da177e4
LT
1001
1002 /* Set up RTS here also ????? RGH 141095 */
44bafdf3
JS
1003 if (i == 0) { /* baud rate is zero, turn off line */
1004 if ((base_addr[CyMSVR2] & CyDTR) == CyDTR)
1005 base_addr[CyMSVR2] = 0;
1da177e4 1006#ifdef SERIAL_DEBUG_DTR
44bafdf3
JS
1007 printk("cyc: %d: dropping DTR\n", __LINE__);
1008 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1009 base_addr[CyMSVR2]);
1da177e4 1010#endif
44bafdf3
JS
1011 } else {
1012 if ((base_addr[CyMSVR2] & CyDTR) != CyDTR)
1013 base_addr[CyMSVR2] = CyDTR;
1da177e4 1014#ifdef SERIAL_DEBUG_DTR
44bafdf3
JS
1015 printk("cyc: %d: raising DTR\n", __LINE__);
1016 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1017 base_addr[CyMSVR2]);
1da177e4
LT
1018#endif
1019 }
1020
44bafdf3
JS
1021 if (info->tty) {
1022 clear_bit(TTY_IO_ERROR, &info->tty->flags);
1da177e4
LT
1023 }
1024
44bafdf3 1025 local_irq_restore(flags);
1da177e4 1026
44bafdf3 1027} /* config_setup */
1da177e4 1028
a5b08c66 1029static int cy_put_char(struct tty_struct *tty, unsigned char ch)
1da177e4 1030{
c9f19e96 1031 struct cyclades_port *info = tty->driver_data;
44bafdf3 1032 unsigned long flags;
1da177e4
LT
1033
1034#ifdef SERIAL_DEBUG_IO
44bafdf3 1035 printk("cy_put_char %s(0x%02x)\n", tty->name, ch);
1da177e4
LT
1036#endif
1037
44bafdf3 1038 if (serial_paranoia_check(info, tty->name, "cy_put_char"))
a5b08c66 1039 return 0;
1da177e4 1040
44bafdf3 1041 if (!info->xmit_buf)
63a59fa7 1042 return 0;
1da177e4 1043
44bafdf3 1044 local_irq_save(flags);
1da177e4 1045 if (info->xmit_cnt >= PAGE_SIZE - 1) {
44bafdf3 1046 local_irq_restore(flags);
a5b08c66 1047 return 0;
1da177e4
LT
1048 }
1049
1050 info->xmit_buf[info->xmit_head++] = ch;
1051 info->xmit_head &= PAGE_SIZE - 1;
1052 info->xmit_cnt++;
44bafdf3 1053 local_irq_restore(flags);
a5b08c66 1054 return 1;
44bafdf3 1055} /* cy_put_char */
1da177e4 1056
44bafdf3 1057static void cy_flush_chars(struct tty_struct *tty)
1da177e4 1058{
c9f19e96 1059 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1060 unsigned long flags;
1061 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1062 int channel;
1063
1da177e4 1064#ifdef SERIAL_DEBUG_IO
44bafdf3 1065 printk("cy_flush_chars %s\n", tty->name); /* */
1da177e4
LT
1066#endif
1067
44bafdf3
JS
1068 if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
1069 return;
1da177e4 1070
44bafdf3
JS
1071 if (info->xmit_cnt <= 0 || tty->stopped
1072 || tty->hw_stopped || !info->xmit_buf)
1073 return;
1da177e4 1074
44bafdf3 1075 channel = info->line;
1da177e4 1076
44bafdf3 1077 local_irq_save(flags);
1da177e4
LT
1078 base_addr[CyCAR] = channel;
1079 base_addr[CyIER] |= CyTxMpty;
44bafdf3
JS
1080 local_irq_restore(flags);
1081} /* cy_flush_chars */
1da177e4
LT
1082
1083/* This routine gets called when tty_write has put something into
1084 the write_queue. If the port is not already transmitting stuff,
1085 start it off by enabling interrupts. The interrupt service
1086 routine will then ensure that the characters are sent. If the
1087 port is already active, there is no need to kick it.
1088 */
44bafdf3 1089static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
1da177e4 1090{
c9f19e96 1091 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1092 unsigned long flags;
1093 int c, total = 0;
1da177e4
LT
1094
1095#ifdef SERIAL_DEBUG_IO
44bafdf3 1096 printk("cy_write %s\n", tty->name); /* */
1da177e4
LT
1097#endif
1098
44bafdf3
JS
1099 if (serial_paranoia_check(info, tty->name, "cy_write")) {
1100 return 0;
1101 }
1da177e4 1102
44bafdf3
JS
1103 if (!info->xmit_buf) {
1104 return 0;
1105 }
1da177e4 1106
44bafdf3
JS
1107 while (1) {
1108 local_irq_save(flags);
1109 c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1110 SERIAL_XMIT_SIZE - info->xmit_head));
1111 if (c <= 0) {
1112 local_irq_restore(flags);
1113 break;
1114 }
1115
1116 memcpy(info->xmit_buf + info->xmit_head, buf, c);
1117 info->xmit_head =
1118 (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
1119 info->xmit_cnt += c;
1120 local_irq_restore(flags);
1121
1122 buf += c;
1123 count -= c;
1124 total += c;
1125 }
1126
1127 if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
1128 start_xmit(info);
1129 }
1130 return total;
1131} /* cy_write */
1132
1133static int cy_write_room(struct tty_struct *tty)
1da177e4 1134{
c9f19e96 1135 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1136 int ret;
1137
1da177e4 1138#ifdef SERIAL_DEBUG_IO
44bafdf3 1139 printk("cy_write_room %s\n", tty->name); /* */
1da177e4
LT
1140#endif
1141
44bafdf3
JS
1142 if (serial_paranoia_check(info, tty->name, "cy_write_room"))
1143 return 0;
1144 ret = PAGE_SIZE - info->xmit_cnt - 1;
1145 if (ret < 0)
1146 ret = 0;
1147 return ret;
1148} /* cy_write_room */
1da177e4 1149
44bafdf3 1150static int cy_chars_in_buffer(struct tty_struct *tty)
1da177e4 1151{
c9f19e96 1152 struct cyclades_port *info = tty->driver_data;
44bafdf3 1153
1da177e4 1154#ifdef SERIAL_DEBUG_IO
44bafdf3 1155 printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */
1da177e4
LT
1156#endif
1157
44bafdf3
JS
1158 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
1159 return 0;
1da177e4 1160
44bafdf3
JS
1161 return info->xmit_cnt;
1162} /* cy_chars_in_buffer */
1da177e4 1163
44bafdf3 1164static void cy_flush_buffer(struct tty_struct *tty)
1da177e4 1165{
c9f19e96 1166 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1167 unsigned long flags;
1168
1da177e4 1169#ifdef SERIAL_DEBUG_IO
44bafdf3 1170 printk("cy_flush_buffer %s\n", tty->name); /* */
1da177e4
LT
1171#endif
1172
44bafdf3
JS
1173 if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
1174 return;
1175 local_irq_save(flags);
1da177e4 1176 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
44bafdf3
JS
1177 local_irq_restore(flags);
1178 tty_wakeup(tty);
1179} /* cy_flush_buffer */
1da177e4
LT
1180
1181/* This routine is called by the upper-layer tty layer to signal
1182 that incoming characters should be throttled or that the
1183 throttle should be released.
1184 */
44bafdf3 1185static void cy_throttle(struct tty_struct *tty)
1da177e4 1186{
c9f19e96 1187 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1188 unsigned long flags;
1189 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1190 int channel;
1da177e4
LT
1191
1192#ifdef SERIAL_DEBUG_THROTTLE
44bafdf3
JS
1193 char buf[64];
1194
1195 printk("throttle %s: %d....\n", tty_name(tty, buf),
1196 tty->ldisc.chars_in_buffer(tty));
1197 printk("cy_throttle %s\n", tty->name);
1da177e4
LT
1198#endif
1199
44bafdf3
JS
1200 if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) {
1201 return;
1202 }
1da177e4 1203
44bafdf3
JS
1204 if (I_IXOFF(tty)) {
1205 info->x_char = STOP_CHAR(tty);
1206 /* Should use the "Send Special Character" feature!!! */
1207 }
1da177e4 1208
44bafdf3 1209 channel = info->line;
1da177e4 1210
44bafdf3
JS
1211 local_irq_save(flags);
1212 base_addr[CyCAR] = (u_char) channel;
1da177e4 1213 base_addr[CyMSVR1] = 0;
44bafdf3
JS
1214 local_irq_restore(flags);
1215} /* cy_throttle */
1da177e4 1216
44bafdf3 1217static void cy_unthrottle(struct tty_struct *tty)
1da177e4 1218{
c9f19e96 1219 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1220 unsigned long flags;
1221 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1222 int channel;
1da177e4
LT
1223
1224#ifdef SERIAL_DEBUG_THROTTLE
44bafdf3
JS
1225 char buf[64];
1226
1227 printk("throttle %s: %d....\n", tty_name(tty, buf),
1228 tty->ldisc.chars_in_buffer(tty));
1229 printk("cy_unthrottle %s\n", tty->name);
1da177e4
LT
1230#endif
1231
44bafdf3
JS
1232 if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) {
1233 return;
1234 }
1da177e4 1235
44bafdf3
JS
1236 if (I_IXOFF(tty)) {
1237 info->x_char = START_CHAR(tty);
1238 /* Should use the "Send Special Character" feature!!! */
1239 }
1da177e4 1240
44bafdf3 1241 channel = info->line;
1da177e4 1242
44bafdf3
JS
1243 local_irq_save(flags);
1244 base_addr[CyCAR] = (u_char) channel;
1da177e4 1245 base_addr[CyMSVR1] = CyRTS;
44bafdf3
JS
1246 local_irq_restore(flags);
1247} /* cy_unthrottle */
1da177e4
LT
1248
1249static int
44bafdf3
JS
1250get_serial_info(struct cyclades_port *info,
1251 struct serial_struct __user * retinfo)
1da177e4 1252{
44bafdf3 1253 struct serial_struct tmp;
1da177e4
LT
1254
1255/* CP('g'); */
44bafdf3
JS
1256 if (!retinfo)
1257 return -EFAULT;
1258 memset(&tmp, 0, sizeof(tmp));
1259 tmp.type = info->type;
1260 tmp.line = info->line;
1261 tmp.port = info->line;
1262 tmp.irq = 0;
1263 tmp.flags = info->flags;
1264 tmp.baud_base = 0; /*!!! */
1265 tmp.close_delay = info->close_delay;
1266 tmp.custom_divisor = 0; /*!!! */
1267 tmp.hub6 = 0; /*!!! */
1268 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
1269} /* get_serial_info */
1da177e4
LT
1270
1271static int
44bafdf3
JS
1272set_serial_info(struct cyclades_port *info,
1273 struct serial_struct __user * new_info)
1da177e4 1274{
44bafdf3
JS
1275 struct serial_struct new_serial;
1276 struct cyclades_port old_info;
1da177e4
LT
1277
1278/* CP('s'); */
44bafdf3
JS
1279 if (!new_info)
1280 return -EFAULT;
1281 if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
1282 return -EFAULT;
1283 old_info = *info;
1284
1285 if (!capable(CAP_SYS_ADMIN)) {
1286 if ((new_serial.close_delay != info->close_delay) ||
1287 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
1288 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
1289 return -EPERM;
1290 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1291 (new_serial.flags & ASYNC_USR_MASK));
1292 goto check_and_exit;
1293 }
1da177e4 1294
44bafdf3
JS
1295 /*
1296 * OK, past this point, all the error checking has been done.
1297 * At this point, we start making changes.....
1298 */
1da177e4 1299
44bafdf3
JS
1300 info->flags = ((info->flags & ~ASYNC_FLAGS) |
1301 (new_serial.flags & ASYNC_FLAGS));
1302 info->close_delay = new_serial.close_delay;
1da177e4 1303
44bafdf3
JS
1304check_and_exit:
1305 if (info->flags & ASYNC_INITIALIZED) {
1306 config_setup(info);
1307 return 0;
1308 }
1309 return startup(info);
1310} /* set_serial_info */
1da177e4 1311
44bafdf3
JS
1312static int cy_tiocmget(struct tty_struct *tty, struct file *file)
1313{
c9f19e96 1314 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1315 int channel;
1316 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1317 unsigned long flags;
1318 unsigned char status;
1da177e4 1319
44bafdf3 1320 channel = info->line;
1da177e4 1321
44bafdf3
JS
1322 local_irq_save(flags);
1323 base_addr[CyCAR] = (u_char) channel;
1324 status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
1325 local_irq_restore(flags);
1da177e4 1326
44bafdf3
JS
1327 return ((status & CyRTS) ? TIOCM_RTS : 0)
1328 | ((status & CyDTR) ? TIOCM_DTR : 0)
1329 | ((status & CyDCD) ? TIOCM_CAR : 0)
1330 | ((status & CyDSR) ? TIOCM_DSR : 0)
1331 | ((status & CyCTS) ? TIOCM_CTS : 0);
1332} /* cy_tiocmget */
1da177e4
LT
1333
1334static int
1335cy_tiocmset(struct tty_struct *tty, struct file *file,
1336 unsigned int set, unsigned int clear)
1337{
c9f19e96 1338 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1339 int channel;
1340 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1341 unsigned long flags;
1342
1343 channel = info->line;
1344
1345 if (set & TIOCM_RTS) {
1346 local_irq_save(flags);
1347 base_addr[CyCAR] = (u_char) channel;
1da177e4 1348 base_addr[CyMSVR1] = CyRTS;
44bafdf3 1349 local_irq_restore(flags);
1da177e4 1350 }
44bafdf3
JS
1351 if (set & TIOCM_DTR) {
1352 local_irq_save(flags);
1353 base_addr[CyCAR] = (u_char) channel;
1da177e4 1354/* CP('S');CP('2'); */
44bafdf3 1355 base_addr[CyMSVR2] = CyDTR;
1da177e4 1356#ifdef SERIAL_DEBUG_DTR
44bafdf3
JS
1357 printk("cyc: %d: raising DTR\n", __LINE__);
1358 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1359 base_addr[CyMSVR2]);
1da177e4 1360#endif
44bafdf3 1361 local_irq_restore(flags);
1da177e4
LT
1362 }
1363
44bafdf3
JS
1364 if (clear & TIOCM_RTS) {
1365 local_irq_save(flags);
1366 base_addr[CyCAR] = (u_char) channel;
1da177e4 1367 base_addr[CyMSVR1] = 0;
44bafdf3 1368 local_irq_restore(flags);
1da177e4 1369 }
44bafdf3
JS
1370 if (clear & TIOCM_DTR) {
1371 local_irq_save(flags);
1372 base_addr[CyCAR] = (u_char) channel;
1da177e4 1373/* CP('C');CP('2'); */
44bafdf3 1374 base_addr[CyMSVR2] = 0;
1da177e4 1375#ifdef SERIAL_DEBUG_DTR
44bafdf3
JS
1376 printk("cyc: %d: dropping DTR\n", __LINE__);
1377 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1378 base_addr[CyMSVR2]);
1da177e4 1379#endif
44bafdf3 1380 local_irq_restore(flags);
1da177e4
LT
1381 }
1382
44bafdf3
JS
1383 return 0;
1384} /* set_modem_info */
1385
1386static void send_break(struct cyclades_port *info, int duration)
1387{ /* Let the transmit ISR take care of this (since it
1388 requires stuffing characters into the output stream).
1389 */
1390 info->x_break = duration;
1391 if (!info->xmit_cnt) {
1392 start_xmit(info);
1393 }
1394} /* send_break */
1da177e4
LT
1395
1396static int
44bafdf3 1397get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon)
1da177e4
LT
1398{
1399
44bafdf3
JS
1400 if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
1401 return -EFAULT;
1402 info->mon.int_count = 0;
1403 info->mon.char_count = 0;
1404 info->mon.char_max = 0;
1405 info->mon.char_last = 0;
1406 return 0;
1da177e4
LT
1407}
1408
44bafdf3 1409static int set_threshold(struct cyclades_port *info, unsigned long __user * arg)
1da177e4 1410{
44bafdf3
JS
1411 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1412 unsigned long value;
1413 int channel;
1414
1415 if (get_user(value, arg))
1416 return -EFAULT;
1417
1418 channel = info->line;
1419 info->cor4 &= ~CyREC_FIFO;
1420 info->cor4 |= value & CyREC_FIFO;
1421 base_addr[CyCOR4] = info->cor4;
1422 return 0;
1da177e4
LT
1423}
1424
1425static int
44bafdf3 1426get_threshold(struct cyclades_port *info, unsigned long __user * value)
1da177e4 1427{
44bafdf3
JS
1428 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1429 int channel;
1430 unsigned long tmp;
1431
1432 channel = info->line;
1433
1434 tmp = base_addr[CyCOR4] & CyREC_FIFO;
1435 return put_user(tmp, value);
1da177e4
LT
1436}
1437
1438static int
44bafdf3 1439set_default_threshold(struct cyclades_port *info, unsigned long __user * arg)
1da177e4 1440{
44bafdf3 1441 unsigned long value;
1da177e4 1442
44bafdf3
JS
1443 if (get_user(value, arg))
1444 return -EFAULT;
1da177e4 1445
44bafdf3
JS
1446 info->default_threshold = value & 0x0f;
1447 return 0;
1da177e4
LT
1448}
1449
1450static int
44bafdf3 1451get_default_threshold(struct cyclades_port *info, unsigned long __user * value)
1da177e4 1452{
44bafdf3 1453 return put_user(info->default_threshold, value);
1da177e4
LT
1454}
1455
44bafdf3 1456static int set_timeout(struct cyclades_port *info, unsigned long __user * arg)
1da177e4 1457{
44bafdf3
JS
1458 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1459 int channel;
1460 unsigned long value;
1461
1462 if (get_user(value, arg))
1463 return -EFAULT;
1464
1465 channel = info->line;
1466
1467 base_addr[CyRTPRL] = value & 0xff;
1468 base_addr[CyRTPRH] = (value >> 8) & 0xff;
1469 return 0;
1da177e4
LT
1470}
1471
44bafdf3 1472static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
1da177e4 1473{
44bafdf3
JS
1474 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1475 int channel;
1476 unsigned long tmp;
1477
1478 channel = info->line;
1479
1480 tmp = base_addr[CyRTPRL];
1481 return put_user(tmp, value);
1da177e4
LT
1482}
1483
44bafdf3 1484static int set_default_timeout(struct cyclades_port *info, unsigned long value)
1da177e4 1485{
44bafdf3
JS
1486 info->default_timeout = value & 0xff;
1487 return 0;
1da177e4
LT
1488}
1489
1490static int
44bafdf3 1491get_default_timeout(struct cyclades_port *info, unsigned long __user * value)
1da177e4 1492{
44bafdf3 1493 return put_user(info->default_timeout, value);
1da177e4
LT
1494}
1495
1496static int
44bafdf3
JS
1497cy_ioctl(struct tty_struct *tty, struct file *file,
1498 unsigned int cmd, unsigned long arg)
1da177e4 1499{
c9f19e96 1500 struct cyclades_port *info = tty->driver_data;
44bafdf3
JS
1501 int ret_val = 0;
1502 void __user *argp = (void __user *)arg;
1da177e4
LT
1503
1504#ifdef SERIAL_DEBUG_OTHER
44bafdf3
JS
1505 printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
1506#endif
1507
638157bc
AC
1508 lock_kernel();
1509
44bafdf3
JS
1510 switch (cmd) {
1511 case CYGETMON:
1512 ret_val = get_mon_info(info, argp);
1513 break;
1514 case CYGETTHRESH:
1515 ret_val = get_threshold(info, argp);
1516 break;
1517 case CYSETTHRESH:
1518 ret_val = set_threshold(info, argp);
1519 break;
1520 case CYGETDEFTHRESH:
1521 ret_val = get_default_threshold(info, argp);
1522 break;
1523 case CYSETDEFTHRESH:
1524 ret_val = set_default_threshold(info, argp);
1525 break;
1526 case CYGETTIMEOUT:
1527 ret_val = get_timeout(info, argp);
1528 break;
1529 case CYSETTIMEOUT:
1530 ret_val = set_timeout(info, argp);
1531 break;
1532 case CYGETDEFTIMEOUT:
1533 ret_val = get_default_timeout(info, argp);
1534 break;
1535 case CYSETDEFTIMEOUT:
1536 ret_val = set_default_timeout(info, (unsigned long)arg);
1537 break;
1538 case TCSBRK: /* SVID version: non-zero arg --> no break */
1539 ret_val = tty_check_change(tty);
1540 if (ret_val)
1541 break;
1542 tty_wait_until_sent(tty, 0);
1543 if (!arg)
1544 send_break(info, HZ / 4); /* 1/4 second */
1545 break;
1546 case TCSBRKP: /* support for POSIX tcsendbreak() */
1547 ret_val = tty_check_change(tty);
1548 if (ret_val)
1549 break;
1550 tty_wait_until_sent(tty, 0);
1551 send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
1da177e4 1552 break;
1da177e4
LT
1553
1554/* The following commands are incompletely implemented!!! */
44bafdf3
JS
1555 case TIOCGSERIAL:
1556 ret_val = get_serial_info(info, argp);
1557 break;
1558 case TIOCSSERIAL:
1559 ret_val = set_serial_info(info, argp);
1560 break;
1561 default:
1562 ret_val = -ENOIOCTLCMD;
1563 }
638157bc 1564 unlock_kernel();
1da177e4
LT
1565
1566#ifdef SERIAL_DEBUG_OTHER
44bafdf3 1567 printk("cy_ioctl done\n");
1da177e4
LT
1568#endif
1569
44bafdf3
JS
1570 return ret_val;
1571} /* cy_ioctl */
1da177e4 1572
44bafdf3 1573static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1da177e4 1574{
c9f19e96 1575 struct cyclades_port *info = tty->driver_data;
1da177e4
LT
1576
1577#ifdef SERIAL_DEBUG_OTHER
44bafdf3 1578 printk("cy_set_termios %s\n", tty->name);
1da177e4
LT
1579#endif
1580
44bafdf3
JS
1581 if (tty->termios->c_cflag == old_termios->c_cflag)
1582 return;
1583 config_setup(info);
1da177e4 1584
44bafdf3
JS
1585 if ((old_termios->c_cflag & CRTSCTS) &&
1586 !(tty->termios->c_cflag & CRTSCTS)) {
1587 tty->stopped = 0;
1588 cy_start(tty);
1589 }
1da177e4 1590#ifdef tytso_patch_94Nov25_1726
44bafdf3
JS
1591 if (!(old_termios->c_cflag & CLOCAL) &&
1592 (tty->termios->c_cflag & CLOCAL))
1593 wake_up_interruptible(&info->open_wait);
1da177e4 1594#endif
44bafdf3 1595} /* cy_set_termios */
1da177e4 1596
44bafdf3 1597static void cy_close(struct tty_struct *tty, struct file *filp)
1da177e4 1598{
c9f19e96 1599 struct cyclades_port *info = tty->driver_data;
1da177e4
LT
1600
1601/* CP('C'); */
1602#ifdef SERIAL_DEBUG_OTHER
44bafdf3 1603 printk("cy_close %s\n", tty->name);
1da177e4
LT
1604#endif
1605
44bafdf3
JS
1606 if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
1607 return;
1608 }
1da177e4 1609#ifdef SERIAL_DEBUG_OPEN
44bafdf3
JS
1610 printk("cy_close %s, count = %d\n", tty->name, info->count);
1611#endif
1612
1613 if ((tty->count == 1) && (info->count != 1)) {
1614 /*
1615 * Uh, oh. tty->count is 1, which means that the tty
1616 * structure will be freed. Info->count should always
1617 * be one in these conditions. If it's greater than
1618 * one, we've got real problems, since it means the
1619 * serial port won't be shutdown.
1620 */
1621 printk("cy_close: bad serial port count; tty->count is 1, "
1622 "info->count is %d\n", info->count);
1623 info->count = 1;
1624 }
1da177e4 1625#ifdef SERIAL_DEBUG_COUNT
44bafdf3
JS
1626 printk("cyc: %d: decrementing count to %d\n", __LINE__,
1627 info->count - 1);
1da177e4 1628#endif
44bafdf3
JS
1629 if (--info->count < 0) {
1630 printk("cy_close: bad serial port count for ttys%d: %d\n",
1631 info->line, info->count);
1da177e4 1632#ifdef SERIAL_DEBUG_COUNT
44bafdf3 1633 printk("cyc: %d: setting count to 0\n", __LINE__);
1da177e4 1634#endif
44bafdf3 1635 info->count = 0;
1da177e4 1636 }
44bafdf3
JS
1637 if (info->count)
1638 return;
1639 info->flags |= ASYNC_CLOSING;
1640 if (info->flags & ASYNC_INITIALIZED)
1641 tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
1642 shutdown(info);
978e595f 1643 cy_flush_buffer(tty);
44bafdf3 1644 tty_ldisc_flush(tty);
44bafdf3
JS
1645 info->tty = NULL;
1646 if (info->blocked_open) {
1647 if (info->close_delay) {
1648 msleep_interruptible(jiffies_to_msecs
1649 (info->close_delay));
1650 }
1651 wake_up_interruptible(&info->open_wait);
1652 }
1653 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1654 wake_up_interruptible(&info->close_wait);
1da177e4
LT
1655
1656#ifdef SERIAL_DEBUG_OTHER
44bafdf3 1657 printk("cy_close done\n");
1da177e4 1658#endif
44bafdf3 1659} /* cy_close */
1da177e4
LT
1660
1661/*
1662 * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
1663 */
44bafdf3 1664void cy_hangup(struct tty_struct *tty)
1da177e4 1665{
c9f19e96 1666 struct cyclades_port *info = tty->driver_data;
44bafdf3 1667
1da177e4 1668#ifdef SERIAL_DEBUG_OTHER
44bafdf3 1669 printk("cy_hangup %s\n", tty->name); /* */
1da177e4
LT
1670#endif
1671
44bafdf3
JS
1672 if (serial_paranoia_check(info, tty->name, "cy_hangup"))
1673 return;
1674
1675 shutdown(info);
1da177e4 1676#if 0
44bafdf3
JS
1677 info->event = 0;
1678 info->count = 0;
1da177e4 1679#ifdef SERIAL_DEBUG_COUNT
44bafdf3 1680 printk("cyc: %d: setting count to 0\n", __LINE__);
1da177e4 1681#endif
44bafdf3 1682 info->tty = 0;
1da177e4 1683#endif
44bafdf3
JS
1684 info->flags &= ~ASYNC_NORMAL_ACTIVE;
1685 wake_up_interruptible(&info->open_wait);
1686} /* cy_hangup */
1da177e4
LT
1687
1688/*
1689 * ------------------------------------------------------------
1690 * cy_open() and friends
1691 * ------------------------------------------------------------
1692 */
1693
1694static int
44bafdf3
JS
1695block_til_ready(struct tty_struct *tty, struct file *filp,
1696 struct cyclades_port *info)
1da177e4 1697{
44bafdf3
JS
1698 DECLARE_WAITQUEUE(wait, current);
1699 unsigned long flags;
1700 int channel;
1701 int retval;
1702 volatile u_char *base_addr = (u_char *) BASE_ADDR;
1703
1704 /*
1705 * If the device is in the middle of being closed, then block
1706 * until it's done, and then try again.
1707 */
1708 if (info->flags & ASYNC_CLOSING) {
1709 interruptible_sleep_on(&info->close_wait);
1710 if (info->flags & ASYNC_HUP_NOTIFY) {
1711 return -EAGAIN;
1712 } else {
1713 return -ERESTARTSYS;
1714 }
1715 }
1716
1717 /*
1718 * If non-blocking mode is set, then make the check up front
1719 * and then exit.
1720 */
1721 if (filp->f_flags & O_NONBLOCK) {
1722 info->flags |= ASYNC_NORMAL_ACTIVE;
1723 return 0;
1724 }
1725
1726 /*
1727 * Block waiting for the carrier detect and the line to become
1728 * free (i.e., not in use by the callout). While we are in
1729 * this loop, info->count is dropped by one, so that
1730 * cy_close() knows when to free things. We restore it upon
1731 * exit, either normal or abnormal.
1732 */
1733 retval = 0;
1734 add_wait_queue(&info->open_wait, &wait);
1da177e4 1735#ifdef SERIAL_DEBUG_OPEN
44bafdf3
JS
1736 printk("block_til_ready before block: %s, count = %d\n",
1737 tty->name, info->count);
1738 /**/
1da177e4 1739#endif
44bafdf3 1740 info->count--;
1da177e4 1741#ifdef SERIAL_DEBUG_COUNT
44bafdf3 1742 printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
1da177e4 1743#endif
44bafdf3 1744 info->blocked_open++;
1da177e4 1745
44bafdf3 1746 channel = info->line;
1da177e4 1747
44bafdf3
JS
1748 while (1) {
1749 local_irq_save(flags);
1750 base_addr[CyCAR] = (u_char) channel;
1751 base_addr[CyMSVR1] = CyRTS;
1da177e4 1752/* CP('S');CP('4'); */
44bafdf3 1753 base_addr[CyMSVR2] = CyDTR;
1da177e4 1754#ifdef SERIAL_DEBUG_DTR
44bafdf3
JS
1755 printk("cyc: %d: raising DTR\n", __LINE__);
1756 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
1757 base_addr[CyMSVR2]);
1758#endif
1759 local_irq_restore(flags);
1760 set_current_state(TASK_INTERRUPTIBLE);
1761 if (tty_hung_up_p(filp)
1762 || !(info->flags & ASYNC_INITIALIZED)) {
1763 if (info->flags & ASYNC_HUP_NOTIFY) {
1764 retval = -EAGAIN;
1765 } else {
1766 retval = -ERESTARTSYS;
1767 }
1768 break;
1769 }
1770 local_irq_save(flags);
1771 base_addr[CyCAR] = (u_char) channel;
1da177e4 1772/* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */
44bafdf3
JS
1773 if (!(info->flags & ASYNC_CLOSING)
1774 && (C_CLOCAL(tty)
1775 || (base_addr[CyMSVR1] & CyDCD))) {
1776 local_irq_restore(flags);
1777 break;
1778 }
1779 local_irq_restore(flags);
1780 if (signal_pending(current)) {
1781 retval = -ERESTARTSYS;
1782 break;
1783 }
1da177e4 1784#ifdef SERIAL_DEBUG_OPEN
44bafdf3
JS
1785 printk("block_til_ready blocking: %s, count = %d\n",
1786 tty->name, info->count);
1787 /**/
1788#endif
1789 schedule();
1790 }
cc0a8fbb 1791 __set_current_state(TASK_RUNNING);
44bafdf3
JS
1792 remove_wait_queue(&info->open_wait, &wait);
1793 if (!tty_hung_up_p(filp)) {
1794 info->count++;
1da177e4 1795#ifdef SERIAL_DEBUG_COUNT
44bafdf3
JS
1796 printk("cyc: %d: incrementing count to %d\n", __LINE__,
1797 info->count);
1da177e4 1798#endif
44bafdf3
JS
1799 }
1800 info->blocked_open--;
1da177e4 1801#ifdef SERIAL_DEBUG_OPEN
44bafdf3
JS
1802 printk("block_til_ready after blocking: %s, count = %d\n",
1803 tty->name, info->count);
1804 /**/
1da177e4 1805#endif
44bafdf3
JS
1806 if (retval)
1807 return retval;
1808 info->flags |= ASYNC_NORMAL_ACTIVE;
1809 return 0;
1810} /* block_til_ready */
1da177e4
LT
1811
1812/*
1813 * This routine is called whenever a serial port is opened. It
1814 * performs the serial-specific initialization for the tty structure.
1815 */
44bafdf3 1816int cy_open(struct tty_struct *tty, struct file *filp)
1da177e4 1817{
44bafdf3
JS
1818 struct cyclades_port *info;
1819 int retval, line;
1da177e4
LT
1820
1821/* CP('O'); */
44bafdf3
JS
1822 line = tty->index;
1823 if ((line < 0) || (NR_PORTS <= line)) {
1824 return -ENODEV;
1825 }
1826 info = &cy_port[line];
1827 if (info->line < 0) {
1828 return -ENODEV;
1829 }
1da177e4 1830#ifdef SERIAL_DEBUG_OTHER
44bafdf3 1831 printk("cy_open %s\n", tty->name); /* */
1da177e4 1832#endif
44bafdf3
JS
1833 if (serial_paranoia_check(info, tty->name, "cy_open")) {
1834 return -ENODEV;
1835 }
1da177e4 1836#ifdef SERIAL_DEBUG_OPEN
44bafdf3
JS
1837 printk("cy_open %s, count = %d\n", tty->name, info->count);
1838 /**/
1da177e4 1839#endif
44bafdf3 1840 info->count++;
1da177e4 1841#ifdef SERIAL_DEBUG_COUNT
44bafdf3 1842 printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
1da177e4 1843#endif
44bafdf3
JS
1844 tty->driver_data = info;
1845 info->tty = tty;
1da177e4 1846
44bafdf3
JS
1847 /*
1848 * Start up serial port
1849 */
1850 retval = startup(info);
1851 if (retval) {
1852 return retval;
1853 }
1da177e4 1854
44bafdf3
JS
1855 retval = block_til_ready(tty, filp, info);
1856 if (retval) {
1da177e4 1857#ifdef SERIAL_DEBUG_OPEN
44bafdf3
JS
1858 printk("cy_open returning after block_til_ready with %d\n",
1859 retval);
1da177e4 1860#endif
44bafdf3
JS
1861 return retval;
1862 }
1da177e4 1863#ifdef SERIAL_DEBUG_OPEN
44bafdf3
JS
1864 printk("cy_open done\n");
1865 /**/
1da177e4 1866#endif
44bafdf3
JS
1867 return 0;
1868} /* cy_open */
1da177e4
LT
1869
1870/*
1871 * ---------------------------------------------------------------------
1872 * serial167_init() and friends
1873 *
1874 * serial167_init() is called at boot-time to initialize the serial driver.
1875 * ---------------------------------------------------------------------
1876 */
1877
1878/*
1879 * This routine prints out the appropriate serial driver version
1880 * number, and identifies which options were configured into this
1881 * driver.
1882 */
44bafdf3 1883static void show_version(void)
1da177e4 1884{
44bafdf3
JS
1885 printk("MVME166/167 cd2401 driver\n");
1886} /* show_version */
1da177e4
LT
1887
1888/* initialize chips on card -- return number of valid
1889 chips (which is number of ports/4) */
1890
1891/*
1892 * This initialises the hardware to a reasonable state. It should
1893 * probe the chip first so as to copy 166-Bug setup as a default for
1894 * port 0. It initialises CMR to CyASYNC; that is never done again, so
1895 * as to limit the number of CyINIT_CHAN commands in normal running.
1896 *
1897 * ... I wonder what I should do if this fails ...
1898 */
1899
44bafdf3 1900void mvme167_serial_console_setup(int cflag)
1da177e4 1901{
44bafdf3 1902 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1da177e4
LT
1903 int ch;
1904 u_char spd;
1905 u_char rcor, rbpr, badspeed = 0;
1906 unsigned long flags;
1907
1908 local_irq_save(flags);
1909
1910 /*
1911 * First probe channel zero of the chip, to see what speed has
1912 * been selected.
1913 */
1914
1915 base_addr[CyCAR] = 0;
1916
1917 rcor = base_addr[CyRCOR] << 5;
1918 rbpr = base_addr[CyRBPR];
1919
1920 for (spd = 0; spd < sizeof(baud_bpr); spd++)
1921 if (rbpr == baud_bpr[spd] && rcor == baud_co[spd])
1922 break;
1923 if (spd >= sizeof(baud_bpr)) {
1924 spd = 14; /* 19200 */
1925 badspeed = 1; /* Failed to identify speed */
1926 }
1927 initial_console_speed = spd;
1928
1929 /* OK, we have chosen a speed, now reset and reinitialise */
1930
44bafdf3
JS
1931 my_udelay(20000L); /* Allow time for any active o/p to complete */
1932 if (base_addr[CyCCR] != 0x00) {
1933 local_irq_restore(flags);
1934 /* printk(" chip is never idle (CCR != 0)\n"); */
1935 return;
1936 }
1da177e4 1937
44bafdf3
JS
1938 base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */
1939 my_udelay(1000L);
1da177e4 1940
44bafdf3
JS
1941 if (base_addr[CyGFRCR] == 0x00) {
1942 local_irq_restore(flags);
1943 /* printk(" chip is not responding (GFRCR stayed 0)\n"); */
1944 return;
1945 }
1da177e4
LT
1946
1947 /*
1948 * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms
1949 * tick
1950 */
1951
1952 base_addr[CyTPR] = 10;
1953
44bafdf3
JS
1954 base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */
1955 base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */
1956 base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */
1da177e4
LT
1957
1958 /*
1959 * Attempt to set up all channels to something reasonable, and
1960 * bang out a INIT_CHAN command. We should then be able to limit
9ddc5b6f 1961 * the amount of fiddling we have to do in normal running.
1da177e4
LT
1962 */
1963
44bafdf3
JS
1964 for (ch = 3; ch >= 0; ch--) {
1965 base_addr[CyCAR] = (u_char) ch;
1da177e4
LT
1966 base_addr[CyIER] = 0;
1967 base_addr[CyCMR] = CyASYNC;
44bafdf3 1968 base_addr[CyLICR] = (u_char) ch << 2;
1da177e4
LT
1969 base_addr[CyLIVR] = 0x5c;
1970 base_addr[CyTCOR] = baud_co[spd];
1971 base_addr[CyTBPR] = baud_bpr[spd];
1972 base_addr[CyRCOR] = baud_co[spd] >> 5;
1973 base_addr[CyRBPR] = baud_bpr[spd];
1974 base_addr[CySCHR1] = 'Q' & 0x1f;
1975 base_addr[CySCHR2] = 'X' & 0x1f;
1976 base_addr[CySCRL] = 0;
1977 base_addr[CySCRH] = 0;
1978 base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
1979 base_addr[CyCOR2] = 0;
1980 base_addr[CyCOR3] = Cy_1_STOP;
1981 base_addr[CyCOR4] = baud_cor4[spd];
1982 base_addr[CyCOR5] = 0;
1983 base_addr[CyCOR6] = 0;
1984 base_addr[CyCOR7] = 0;
1985 base_addr[CyRTPRL] = 2;
1986 base_addr[CyRTPRH] = 0;
44bafdf3
JS
1987 base_addr[CyMSVR1] = 0;
1988 base_addr[CyMSVR2] = 0;
1989 write_cy_cmd(base_addr, CyINIT_CHAN | CyDIS_RCVR | CyDIS_XMTR);
1da177e4
LT
1990 }
1991
1992 /*
1993 * Now do specials for channel zero....
1994 */
1995
44bafdf3
JS
1996 base_addr[CyMSVR1] = CyRTS;
1997 base_addr[CyMSVR2] = CyDTR;
1da177e4 1998 base_addr[CyIER] = CyRxData;
44bafdf3 1999 write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR);
1da177e4
LT
2000
2001 local_irq_restore(flags);
2002
2003 my_udelay(20000L); /* Let it all settle down */
2004
44bafdf3 2005 printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]);
1da177e4 2006 if (badspeed)
44bafdf3
JS
2007 printk
2008 (" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n",
2009 rcor >> 5, rbpr);
2010} /* serial_console_init */
1da177e4 2011
b68e31d0 2012static const struct tty_operations cy_ops = {
1da177e4
LT
2013 .open = cy_open,
2014 .close = cy_close,
2015 .write = cy_write,
2016 .put_char = cy_put_char,
2017 .flush_chars = cy_flush_chars,
2018 .write_room = cy_write_room,
2019 .chars_in_buffer = cy_chars_in_buffer,
2020 .flush_buffer = cy_flush_buffer,
2021 .ioctl = cy_ioctl,
2022 .throttle = cy_throttle,
2023 .unthrottle = cy_unthrottle,
2024 .set_termios = cy_set_termios,
2025 .stop = cy_stop,
2026 .start = cy_start,
2027 .hangup = cy_hangup,
2028 .tiocmget = cy_tiocmget,
2029 .tiocmset = cy_tiocmset,
2030};
44bafdf3 2031
1da177e4
LT
2032/* The serial driver boot-time initialization code!
2033 Hardware I/O ports are mapped to character special devices on a
2034 first found, first allocated manner. That is, this code searches
2035 for Cyclom cards in the system. As each is found, it is probed
2036 to discover how many chips (and thus how many ports) are present.
2037 These ports are mapped to the tty ports 64 and upward in monotonic
2038 fashion. If an 8-port card is replaced with a 16-port card, the
2039 port mapping on a following card will shift.
2040
2041 This approach is different from what is used in the other serial
2042 device driver because the Cyclom is more properly a multiplexer,
2043 not just an aggregation of serial ports on one card.
2044
2045 If there are more cards with more ports than have been statically
2046 allocated above, a warning is printed and the extra ports are ignored.
2047 */
44bafdf3 2048static int __init serial167_init(void)
1da177e4 2049{
44bafdf3
JS
2050 struct cyclades_port *info;
2051 int ret = 0;
2052 int good_ports = 0;
2053 int port_num = 0;
2054 int index;
2055 int DefSpeed;
1da177e4 2056#ifdef notyet
44bafdf3 2057 struct sigaction sa;
1da177e4
LT
2058#endif
2059
44bafdf3
JS
2060 if (!(mvme16x_config & MVME16x_CONFIG_GOT_CD2401))
2061 return 0;
1da177e4 2062
44bafdf3
JS
2063 cy_serial_driver = alloc_tty_driver(NR_PORTS);
2064 if (!cy_serial_driver)
2065 return -ENOMEM;
1da177e4
LT
2066
2067#if 0
44bafdf3 2068 scrn[1] = '\0';
1da177e4
LT
2069#endif
2070
44bafdf3 2071 show_version();
1da177e4 2072
44bafdf3
JS
2073 /* Has "console=0,9600n8" been used in bootinfo to change speed? */
2074 if (serial_console_cflag)
2075 DefSpeed = serial_console_cflag & 0017;
2076 else {
2077 DefSpeed = initial_console_speed;
2078 serial_console_info = &cy_port[0];
2079 serial_console_cflag = DefSpeed | CS8;
1da177e4 2080#if 0
44bafdf3
JS
2081 serial_console = 64; /*callout_driver.minor_start */
2082#endif
2083 }
1da177e4 2084
44bafdf3 2085 /* Initialize the tty_driver structure */
1da177e4 2086
44bafdf3
JS
2087 cy_serial_driver->owner = THIS_MODULE;
2088 cy_serial_driver->name = "ttyS";
2089 cy_serial_driver->major = TTY_MAJOR;
2090 cy_serial_driver->minor_start = 64;
2091 cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
2092 cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
2093 cy_serial_driver->init_termios = tty_std_termios;
2094 cy_serial_driver->init_termios.c_cflag =
2095 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2096 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
2097 tty_set_operations(cy_serial_driver, &cy_ops);
2098
2099 ret = tty_register_driver(cy_serial_driver);
2100 if (ret) {
2101 printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
2102 put_tty_driver(cy_serial_driver);
2103 return ret;
2104 }
1da177e4 2105
44bafdf3
JS
2106 port_num = 0;
2107 info = cy_port;
2108 for (index = 0; index < 1; index++) {
1da177e4 2109
44bafdf3
JS
2110 good_ports = 4;
2111
2112 if (port_num < NR_PORTS) {
2113 while (good_ports-- && port_num < NR_PORTS) {
1da177e4 2114 /*** initialize port ***/
44bafdf3
JS
2115 info->magic = CYCLADES_MAGIC;
2116 info->type = PORT_CIRRUS;
2117 info->card = index;
2118 info->line = port_num;
2119 info->flags = STD_COM_FLAGS;
2120 info->tty = NULL;
2121 info->xmit_fifo_size = 12;
2122 info->cor1 = CyPARITY_NONE | Cy_8_BITS;
2123 info->cor2 = CyETC;
2124 info->cor3 = Cy_1_STOP;
2125 info->cor4 = 0x08; /* _very_ small receive threshold */
2126 info->cor5 = 0;
2127 info->cor6 = 0;
2128 info->cor7 = 0;
2129 info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */
2130 info->tco = baud_co[DefSpeed]; /* Tx CO */
2131 info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */
2132 info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */
2133 info->close_delay = 0;
2134 info->x_char = 0;
44bafdf3 2135 info->count = 0;
1da177e4 2136#ifdef SERIAL_DEBUG_COUNT
44bafdf3
JS
2137 printk("cyc: %d: setting count to 0\n",
2138 __LINE__);
2139#endif
2140 info->blocked_open = 0;
2141 info->default_threshold = 0;
2142 info->default_timeout = 0;
44bafdf3
JS
2143 init_waitqueue_head(&info->open_wait);
2144 init_waitqueue_head(&info->close_wait);
2145 /* info->session */
2146 /* info->pgrp */
1da177e4 2147/*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/
44bafdf3
JS
2148 info->read_status_mask =
2149 CyTIMEOUT | CySPECHAR | CyBREAK | CyPARITY |
2150 CyFRAME | CyOVERRUN;
2151 /* info->timeout */
2152
2153 printk("ttyS%d ", info->line);
2154 port_num++;
2155 info++;
2156 if (!(port_num & 7)) {
2157 printk("\n ");
2158 }
2159 }
1da177e4 2160 }
44bafdf3
JS
2161 printk("\n");
2162 }
2163 while (port_num < NR_PORTS) {
2164 info->line = -1;
2165 port_num++;
2166 info++;
2167 }
0dbb5671 2168
44bafdf3
JS
2169 ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
2170 "cd2401_errors", cd2401_rxerr_interrupt);
2171 if (ret) {
2172 printk(KERN_ERR "Could't get cd2401_errors IRQ");
2173 goto cleanup_serial_driver;
2174 }
2175
2176 ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
2177 "cd2401_modem", cd2401_modem_interrupt);
2178 if (ret) {
2179 printk(KERN_ERR "Could't get cd2401_modem IRQ");
2180 goto cleanup_irq_cd2401_errors;
2181 }
2182
2183 ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
2184 "cd2401_txints", cd2401_tx_interrupt);
2185 if (ret) {
2186 printk(KERN_ERR "Could't get cd2401_txints IRQ");
2187 goto cleanup_irq_cd2401_modem;
2188 }
2189
2190 ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
2191 "cd2401_rxints", cd2401_rx_interrupt);
2192 if (ret) {
2193 printk(KERN_ERR "Could't get cd2401_rxints IRQ");
2194 goto cleanup_irq_cd2401_txints;
2195 }
2196
2197 /* Now we have registered the interrupt handlers, allow the interrupts */
2198
2199 pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */
2200 pcc2chip[PccSCCTICR] = 0x15;
2201 pcc2chip[PccSCCRICR] = 0x15;
2202
2203 pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */
2204
2205 return 0;
1da177e4 2206cleanup_irq_cd2401_txints:
44bafdf3 2207 free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt);
1da177e4 2208cleanup_irq_cd2401_modem:
44bafdf3 2209 free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
1da177e4 2210cleanup_irq_cd2401_errors:
44bafdf3 2211 free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
1da177e4 2212cleanup_serial_driver:
44bafdf3
JS
2213 if (tty_unregister_driver(cy_serial_driver))
2214 printk(KERN_ERR
2215 "Couldn't unregister MVME166/7 serial driver\n");
2216 put_tty_driver(cy_serial_driver);
2217 return ret;
2218} /* serial167_init */
1da177e4
LT
2219
2220module_init(serial167_init);
2221
1da177e4 2222#ifdef CYCLOM_SHOW_STATUS
44bafdf3 2223static void show_status(int line_num)
1da177e4 2224{
44bafdf3
JS
2225 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
2226 int channel;
2227 struct cyclades_port *info;
2228 unsigned long flags;
2229
2230 info = &cy_port[line_num];
2231 channel = info->line;
2232 printk(" channel %d\n", channel);
2233 /**/ printk(" cy_port\n");
2234 printk(" card line flags = %d %d %x\n",
2235 info->card, info->line, info->flags);
2236 printk
2237 (" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
2238 (long)info->tty, info->read_status_mask, info->timeout,
2239 info->xmit_fifo_size);
2240 printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n",
2241 info->cor1, info->cor2, info->cor3, info->cor4, info->cor5,
2242 info->cor6, info->cor7);
2243 printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n", info->tbpr, info->tco,
2244 info->rbpr, info->rco);
2245 printk(" close_delay event count = %d %d %d\n", info->close_delay,
2246 info->event, info->count);
2247 printk(" x_char blocked_open = %x %x\n", info->x_char,
2248 info->blocked_open);
2249 printk(" open_wait = %lx %lx %lx\n", (long)info->open_wait);
2250
2251 local_irq_save(flags);
1da177e4
LT
2252
2253/* Global Registers */
2254
2255 printk(" CyGFRCR %x\n", base_addr[CyGFRCR]);
2256 printk(" CyCAR %x\n", base_addr[CyCAR]);
2257 printk(" CyRISR %x\n", base_addr[CyRISR]);
2258 printk(" CyTISR %x\n", base_addr[CyTISR]);
2259 printk(" CyMISR %x\n", base_addr[CyMISR]);
2260 printk(" CyRIR %x\n", base_addr[CyRIR]);
2261 printk(" CyTIR %x\n", base_addr[CyTIR]);
2262 printk(" CyMIR %x\n", base_addr[CyMIR]);
2263 printk(" CyTPR %x\n", base_addr[CyTPR]);
2264
44bafdf3 2265 base_addr[CyCAR] = (u_char) channel;
1da177e4
LT
2266
2267/* Virtual Registers */
2268
2269#if 0
2270 printk(" CyRIVR %x\n", base_addr[CyRIVR]);
2271 printk(" CyTIVR %x\n", base_addr[CyTIVR]);
2272 printk(" CyMIVR %x\n", base_addr[CyMIVR]);
2273 printk(" CyMISR %x\n", base_addr[CyMISR]);
2274#endif
2275
2276/* Channel Registers */
2277
2278 printk(" CyCCR %x\n", base_addr[CyCCR]);
2279 printk(" CyIER %x\n", base_addr[CyIER]);
2280 printk(" CyCOR1 %x\n", base_addr[CyCOR1]);
2281 printk(" CyCOR2 %x\n", base_addr[CyCOR2]);
2282 printk(" CyCOR3 %x\n", base_addr[CyCOR3]);
2283 printk(" CyCOR4 %x\n", base_addr[CyCOR4]);
2284 printk(" CyCOR5 %x\n", base_addr[CyCOR5]);
2285#if 0
2286 printk(" CyCCSR %x\n", base_addr[CyCCSR]);
2287 printk(" CyRDCR %x\n", base_addr[CyRDCR]);
2288#endif
2289 printk(" CySCHR1 %x\n", base_addr[CySCHR1]);
2290 printk(" CySCHR2 %x\n", base_addr[CySCHR2]);
2291#if 0
2292 printk(" CySCHR3 %x\n", base_addr[CySCHR3]);
2293 printk(" CySCHR4 %x\n", base_addr[CySCHR4]);
2294 printk(" CySCRL %x\n", base_addr[CySCRL]);
2295 printk(" CySCRH %x\n", base_addr[CySCRH]);
2296 printk(" CyLNC %x\n", base_addr[CyLNC]);
2297 printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]);
2298 printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]);
2299#endif
2300 printk(" CyRTPRL %x\n", base_addr[CyRTPRL]);
2301 printk(" CyRTPRH %x\n", base_addr[CyRTPRH]);
2302 printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]);
2303 printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]);
2304 printk(" CyRBPR %x\n", base_addr[CyRBPR]);
2305 printk(" CyRCOR %x\n", base_addr[CyRCOR]);
2306 printk(" CyTBPR %x\n", base_addr[CyTBPR]);
2307 printk(" CyTCOR %x\n", base_addr[CyTCOR]);
2308
44bafdf3
JS
2309 local_irq_restore(flags);
2310} /* show_status */
1da177e4
LT
2311#endif
2312
1da177e4
LT
2313#if 0
2314/* Dummy routine in mvme16x/config.c for now */
2315
2316/* Serial console setup. Called from linux/init/main.c */
2317
2318void console_setup(char *str, int *ints)
2319{
2320 char *s;
2321 int baud, bits, parity;
2322 int cflag = 0;
2323
2324 /* Sanity check. */
44bafdf3
JS
2325 if (ints[0] > 3 || ints[1] > 3)
2326 return;
1da177e4
LT
2327
2328 /* Get baud, bits and parity */
2329 baud = 2400;
2330 bits = 8;
2331 parity = 'n';
44bafdf3
JS
2332 if (ints[2])
2333 baud = ints[2];
1da177e4
LT
2334 if ((s = strchr(str, ','))) {
2335 do {
2336 s++;
44bafdf3
JS
2337 } while (*s >= '0' && *s <= '9');
2338 if (*s)
2339 parity = *s++;
2340 if (*s)
2341 bits = *s - '0';
1da177e4
LT
2342 }
2343
2344 /* Now construct a cflag setting. */
44bafdf3
JS
2345 switch (baud) {
2346 case 1200:
2347 cflag |= B1200;
2348 break;
2349 case 9600:
2350 cflag |= B9600;
2351 break;
2352 case 19200:
2353 cflag |= B19200;
2354 break;
2355 case 38400:
2356 cflag |= B38400;
2357 break;
2358 case 2400:
2359 default:
2360 cflag |= B2400;
2361 break;
1da177e4 2362 }
44bafdf3
JS
2363 switch (bits) {
2364 case 7:
2365 cflag |= CS7;
2366 break;
2367 default:
2368 case 8:
2369 cflag |= CS8;
2370 break;
1da177e4 2371 }
44bafdf3
JS
2372 switch (parity) {
2373 case 'o':
2374 case 'O':
2375 cflag |= PARODD;
2376 break;
2377 case 'e':
2378 case 'E':
2379 cflag |= PARENB;
2380 break;
1da177e4
LT
2381 }
2382
2383 serial_console_info = &cy_port[ints[1]];
2384 serial_console_cflag = cflag;
44bafdf3 2385 serial_console = ints[1] + 64; /*callout_driver.minor_start */
1da177e4
LT
2386}
2387#endif
2388
2389/*
2390 * The following is probably out of date for 2.1.x serial console stuff.
2391 *
2392 * The console is registered early on from arch/m68k/kernel/setup.c, and
2393 * it therefore relies on the chip being setup correctly by 166-Bug. This
2394 * seems reasonable, as the serial port has been used to invoke the system
2395 * boot. It also means that this function must not rely on any data
2396 * initialisation performed by serial167_init() etc.
2397 *
2398 * Of course, once the console has been registered, we had better ensure
2399 * that serial167_init() doesn't leave the chip non-functional.
2400 *
2401 * The console must be locked when we get here.
2402 */
2403
44bafdf3
JS
2404void serial167_console_write(struct console *co, const char *str,
2405 unsigned count)
1da177e4 2406{
44bafdf3 2407 volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
1da177e4
LT
2408 unsigned long flags;
2409 volatile u_char sink;
2410 u_char ier;
2411 int port;
2412 u_char do_lf = 0;
2413 int i = 0;
2414
2415 local_irq_save(flags);
2416
2417 /* Ensure transmitter is enabled! */
2418
2419 port = 0;
44bafdf3 2420 base_addr[CyCAR] = (u_char) port;
1da177e4
LT
2421 while (base_addr[CyCCR])
2422 ;
2423 base_addr[CyCCR] = CyENB_XMTR;
2424
2425 ier = base_addr[CyIER];
2426 base_addr[CyIER] = CyTxMpty;
2427
2428 while (1) {
44bafdf3 2429 if (pcc2chip[PccSCCTICR] & 0x20) {
1da177e4
LT
2430 /* We have a Tx int. Acknowledge it */
2431 sink = pcc2chip[PccTPIACKR];
2432 if ((base_addr[CyLICR] >> 2) == port) {
2433 if (i == count) {
2434 /* Last char of string is now output */
2435 base_addr[CyTEOIR] = CyNOTRANS;
2436 break;
2437 }
2438 if (do_lf) {
2439 base_addr[CyTDR] = '\n';
2440 str++;
2441 i++;
2442 do_lf = 0;
44bafdf3 2443 } else if (*str == '\n') {
1da177e4
LT
2444 base_addr[CyTDR] = '\r';
2445 do_lf = 1;
44bafdf3 2446 } else {
1da177e4
LT
2447 base_addr[CyTDR] = *str++;
2448 i++;
2449 }
2450 base_addr[CyTEOIR] = 0;
44bafdf3 2451 } else
1da177e4
LT
2452 base_addr[CyTEOIR] = CyNOTRANS;
2453 }
2454 }
2455
2456 base_addr[CyIER] = ier;
2457
2458 local_irq_restore(flags);
2459}
2460
44bafdf3
JS
2461static struct tty_driver *serial167_console_device(struct console *c,
2462 int *index)
1da177e4
LT
2463{
2464 *index = c->index;
2465 return cy_serial_driver;
2466}
2467
1da177e4 2468static struct console sercons = {
44bafdf3
JS
2469 .name = "ttyS",
2470 .write = serial167_console_write,
2471 .device = serial167_console_device,
44bafdf3
JS
2472 .flags = CON_PRINTBUFFER,
2473 .index = -1,
1da177e4
LT
2474};
2475
1da177e4
LT
2476static int __init serial167_console_init(void)
2477{
2478 if (vme_brdtype == VME_TYPE_MVME166 ||
44bafdf3
JS
2479 vme_brdtype == VME_TYPE_MVME167 ||
2480 vme_brdtype == VME_TYPE_MVME177) {
1da177e4
LT
2481 mvme167_serial_console_setup(0);
2482 register_console(&sercons);
2483 }
2484 return 0;
2485}
44bafdf3 2486
1da177e4
LT
2487console_initcall(serial167_console_init);
2488
1da177e4 2489MODULE_LICENSE("GPL");