ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / serial_tx3912.c
1 /*
2  *  drivers/char/serial_tx3912.c
3  *
4  *  Copyright (C) 1999 Harald Koerfgen
5  *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
6  *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *  
12  *  Serial driver for TMPR3912/05 and PR31700 processors
13  */
14 #include <linux/init.h>
15 #include <linux/config.h>
16 #include <linux/tty.h>
17 #include <linux/major.h>
18 #include <linux/ptrace.h>
19 #include <linux/console.h>
20 #include <linux/fs.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/module.h>
24 #include <linux/delay.h>
25 #include <linux/pm.h>
26 #include <asm/io.h>
27 #include <asm/uaccess.h>
28 #include <asm/delay.h>
29 #include <asm/wbflush.h>
30 #include <asm/tx3912.h>
31 #include "serial_tx3912.h"
32
33 /*
34  * Forward declarations for serial routines
35  */
36 static void rs_disable_tx_interrupts (void * ptr);
37 static void rs_enable_tx_interrupts (void * ptr); 
38 static void rs_disable_rx_interrupts (void * ptr); 
39 static void rs_enable_rx_interrupts (void * ptr); 
40 static int rs_get_CD (void * ptr); 
41 static void rs_shutdown_port (void * ptr); 
42 static int rs_set_real_termios (void *ptr);
43 static int rs_chars_in_buffer (void * ptr); 
44
45 /*
46  * Used by generic serial driver to access hardware
47  */
48 static struct real_driver rs_real_driver = { 
49         .disable_tx_interrupts = rs_disable_tx_interrupts, 
50         .enable_tx_interrupts  = rs_enable_tx_interrupts, 
51         .disable_rx_interrupts = rs_disable_rx_interrupts, 
52         .enable_rx_interrupts  = rs_enable_rx_interrupts, 
53         .get_CD                = rs_get_CD, 
54         .shutdown_port         = rs_shutdown_port,  
55         .set_real_termios      = rs_set_real_termios,  
56         .chars_in_buffer       = rs_chars_in_buffer, 
57 }; 
58
59 /*
60  * Structures and such for TTY sessions and usage counts
61  */
62 static struct tty_driver *rs_driver;
63 struct rs_port *rs_ports;
64 int rs_initialized = 0;
65
66 /*
67  * ----------------------------------------------------------------------
68  *
69  * Here starts the interrupt handling routines.  All of the following
70  * subroutines are declared as inline and are folded into
71  * rs_interrupt().  They were separated out for readability's sake.
72  *
73  * Note: rs_interrupt() is a "fast" interrupt, which means that it
74  * runs with interrupts turned off.  People who may want to modify
75  * rs_interrupt() should try to keep the interrupt handler as fast as
76  * possible.  After you are done making modifications, it is not a bad
77  * idea to do:
78  * 
79  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
80  *
81  * and look at the resulting assemble code in serial.s.
82  *
83  *                              - Ted Ts'o (tytso@mit.edu), 7-Mar-93
84  * -----------------------------------------------------------------------
85  */
86 static inline void receive_char_pio(struct rs_port *port)
87 {
88         struct tty_struct *tty = port->gs.tty;
89         unsigned char ch;
90         int counter = 2048;
91
92         /* While there are characters, get them ... */
93         while (counter>0) {
94                 if (!(inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL))
95                         break;
96                 ch = inb(port->base + TX3912_UART_DATA);
97                 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
98                         *tty->flip.char_buf_ptr++ = ch;
99                         *tty->flip.flag_buf_ptr++ = 0;
100                         tty->flip.count++;
101                 }
102                 udelay(1); /* Allow things to happen - it take a while */
103                 counter--;
104         }
105         if (!counter)
106                 printk( "Ugh, looped in receive_char_pio!\n" );
107
108         tty_flip_buffer_push(tty);
109
110 #if 0
111         /* Now handle error conditions */
112         if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
113                         INTTYPE(UART_FRAMEERR_INT) |
114                         INTTYPE(UART_PARITYERR_INT) |
115                         INTTYPE(UART_BREAK_INT))) {
116
117                 /*
118                  * Now check to see if character should be
119                  * ignored, and mask off conditions which
120                  * should be ignored.
121                  */
122                 if (*status & port->ignore_status_mask) {
123                         goto ignore_char;
124                 }
125                 *status &= port->read_status_mask;
126                 
127                 if (*status & INTTYPE(UART_BREAK_INT)) {
128                         rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "handling break....");
129                         *tty->flip.flag_buf_ptr = TTY_BREAK;
130                 }
131                 else if (*status & INTTYPE(UART_PARITYERR_INT)) {
132                         *tty->flip.flag_buf_ptr = TTY_PARITY;
133                 }
134                 else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
135                         *tty->flip.flag_buf_ptr = TTY_FRAME;
136                 }
137                 if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
138                         /*
139                          * Overrun is special, since it's
140                          * reported immediately, and doesn't
141                          * affect the current character
142                          */
143                         if (tty->flip.count < TTY_FLIPBUF_SIZE) {
144                                 tty->flip.count++;
145                                 tty->flip.flag_buf_ptr++;
146                                 tty->flip.char_buf_ptr++;
147                                 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
148                         }
149                 }
150         }
151
152         tty->flip.flag_buf_ptr++;
153         tty->flip.char_buf_ptr++;
154         tty->flip.count++;
155
156 ignore_char:
157         tty_flip_buffer_push(tty);
158 #endif
159 }
160
161 static inline void transmit_char_pio(struct rs_port *port)
162 {
163         /* While I'm able to transmit ... */
164         for (;;) {
165                 if (!(inl(port->base + TX3912_UART_CTRL1) & UART_TX_EMPTY))
166                         break;
167                 else if (port->x_char) {
168                         outb(port->x_char, port->base + TX3912_UART_DATA);
169                         port->icount.tx++;
170                         port->x_char = 0;
171                 }
172                 else if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
173                     port->gs.tty->hw_stopped) {
174                         break;
175                 }
176                 else {
177                         outb(port->gs.xmit_buf[port->gs.xmit_tail++],
178                                 port->base + TX3912_UART_DATA);
179                         port->icount.tx++;
180                         port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
181                         if (--port->gs.xmit_cnt <= 0) {
182                                 break;
183                         }
184                 }
185                 udelay(10); /* Allow things to happen - it take a while */
186         }
187
188         if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
189              port->gs.tty->hw_stopped) {
190                 rs_disable_tx_interrupts(port);
191         }
192         
193         if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
194                 if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
195                     port->gs.tty->ldisc.write_wakeup)
196                         (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
197                 rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
198                             port->gs.wakeup_chars); 
199                 wake_up_interruptible(&port->gs.tty->write_wait);
200         }       
201 }
202
203
204
205 static inline void check_modem_status(struct rs_port *port)
206 {
207         /* We don't have a carrier detect line - but just respond
208            like we had one anyways so that open() becomes unblocked */
209         wake_up_interruptible(&port->gs.open_wait);
210 }
211
212 int count = 0;
213
214 /*
215  * This is the serial driver's interrupt routine (inlined, because
216  * there are two different versions of this, one for each serial port,
217  * differing only by the bits used in interrupt status 2 register)
218  */
219
220 static inline void rs_rx_interrupt(int irq, void *dev_id,
221                                   struct pt_regs * regs, int intshift)
222 {
223         struct rs_port * port;
224         unsigned long int2status;
225         unsigned long flags;
226         unsigned long ints;
227
228         save_and_cli(flags);
229
230         port = (struct rs_port *)dev_id;
231         rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
232
233         /* Get the interrrupts we have enabled */
234         int2status = IntStatus2 & IntEnable2;
235
236         /* Get interrupts in easy to use form */
237         ints = int2status >> intshift;
238
239         /* Clear any interrupts we might be about to handle */
240         IntClear2 = int2status & (
241                 (INTTYPE(UART_RXOVERRUN_INT) |
242                  INTTYPE(UART_FRAMEERR_INT) |
243                  INTTYPE(UART_BREAK_INT) |
244                  INTTYPE(UART_PARITYERR_INT) |
245                  INTTYPE(UART_RX_INT)) << intshift);
246
247         if (!port || !port->gs.tty) {
248                 restore_flags(flags);
249                 return;
250         }
251
252         /* RX Receiver Holding Register Overrun */
253         if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
254                 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "overrun");
255                 port->icount.overrun++;
256         }
257
258         /* RX Frame Error */
259         if (ints & INTTYPE(UART_FRAMEERR_INT)) {
260                 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "frame error");
261                 port->icount.frame++;
262         }
263
264         /* Break signal received */
265         if (ints & INTTYPE(UART_BREAK_INT)) {
266                 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "break");
267                 port->icount.brk++;
268         }
269
270         /* RX Parity Error */
271         if (ints & INTTYPE(UART_PARITYERR_INT)) {
272                 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "parity error");
273                 port->icount.parity++;
274         }
275
276         /* Receive byte (non-DMA) */
277         if (ints & INTTYPE(UART_RX_INT)) {
278                 receive_char_pio(port);
279         }
280
281         restore_flags(flags);
282
283         rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
284 }
285
286 static inline void rs_tx_interrupt(int irq, void *dev_id,
287                                   struct pt_regs * regs, int intshift)
288 {
289         struct rs_port * port;
290         unsigned long int2status;
291         unsigned long flags;
292         unsigned long ints;
293
294         save_and_cli(flags);
295
296         port = (struct rs_port *)dev_id;
297         rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
298
299         /* Get the interrrupts we have enabled */
300         int2status = IntStatus2 & IntEnable2;
301
302         if (!port || !port->gs.tty) {
303                 restore_flags(flags);
304                 return;
305         }
306
307         /* Get interrupts in easy to use form */
308         ints = int2status >> intshift;
309
310         /* Clear any interrupts we might be about to handle */
311         IntClear2 = int2status & (
312                 (INTTYPE(UART_TX_INT) |
313                  INTTYPE(UART_EMPTY_INT) |
314                  INTTYPE(UART_TXOVERRUN_INT)) << intshift);
315
316         /* TX holding register empty, so transmit byte (non-DMA) */
317         if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
318                 transmit_char_pio(port);
319         }
320
321         /* TX Transmit Holding Register Overrun (shouldn't happen) */
322         if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
323                 printk ( "rs: TX overrun\n");
324         }
325
326         /*
327         check_modem_status();
328         */
329
330         restore_flags(flags);
331
332         rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
333 }
334
335 static void rs_rx_interrupt_uarta(int irq, void *dev_id,
336                                          struct pt_regs * regs)
337 {
338         rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
339 }
340
341 static void rs_tx_interrupt_uarta(int irq, void *dev_id,
342                                          struct pt_regs * regs)
343 {
344         rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
345 }
346
347 /*
348  ***********************************************************************
349  *                Here are the routines that actually                  *
350  *              interface with the generic_serial driver               *
351  ***********************************************************************
352  */
353 static void rs_disable_tx_interrupts (void * ptr) 
354 {
355         struct rs_port *port = ptr; 
356         unsigned long flags;
357
358         save_and_cli(flags);
359         port->gs.flags &= ~GS_TX_INTEN;
360
361         IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
362                         INTTYPE(UART_EMPTY_INT) |
363                         INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
364
365         IntClear2 = (INTTYPE(UART_TX_INT) |
366                         INTTYPE(UART_EMPTY_INT) |
367                         INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
368
369         restore_flags(flags);
370 }
371
372 static void rs_enable_tx_interrupts (void * ptr) 
373 {
374         struct rs_port *port = ptr; 
375         unsigned long flags;
376
377         save_and_cli(flags);
378
379         IntClear2 = (INTTYPE(UART_TX_INT) |
380                         INTTYPE(UART_EMPTY_INT) |
381                         INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
382
383         IntEnable2 |= (INTTYPE(UART_TX_INT) |
384                         INTTYPE(UART_EMPTY_INT) |
385                         INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
386
387         /* Send a char to start TX interrupts happening */
388         transmit_char_pio(port);
389
390         restore_flags(flags);
391 }
392
393 static void rs_disable_rx_interrupts (void * ptr) 
394 {
395         struct rs_port *port = ptr;
396         unsigned long flags;
397
398         save_and_cli(flags);
399
400         IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
401                          INTTYPE(UART_RXOVERRUN_INT) |
402                          INTTYPE(UART_FRAMEERR_INT) |
403                          INTTYPE(UART_BREAK_INT) |
404                          INTTYPE(UART_PARITYERR_INT)) << port->intshift);
405
406         IntClear2 = (INTTYPE(UART_RX_INT) |
407                          INTTYPE(UART_RXOVERRUN_INT) |
408                          INTTYPE(UART_FRAMEERR_INT) |
409                          INTTYPE(UART_BREAK_INT) |
410                          INTTYPE(UART_PARITYERR_INT)) << port->intshift;
411
412         restore_flags(flags);
413 }
414
415 static void rs_enable_rx_interrupts (void * ptr) 
416 {
417         struct rs_port *port = ptr;
418         unsigned long flags;
419
420         save_and_cli(flags);
421
422         IntEnable2 |= (INTTYPE(UART_RX_INT) |
423                          INTTYPE(UART_RXOVERRUN_INT) |
424                          INTTYPE(UART_FRAMEERR_INT) |
425                          INTTYPE(UART_BREAK_INT) |
426                          INTTYPE(UART_PARITYERR_INT)) << port->intshift;
427
428         /* Empty the input buffer - apparently this is *vital* */
429         while (inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL) { 
430                 inb(port->base + TX3912_UART_DATA);
431         }
432
433         IntClear2 = (INTTYPE(UART_RX_INT) |
434                          INTTYPE(UART_RXOVERRUN_INT) |
435                          INTTYPE(UART_FRAMEERR_INT) |
436                          INTTYPE(UART_BREAK_INT) |
437                          INTTYPE(UART_PARITYERR_INT)) << port->intshift;
438
439         restore_flags(flags);
440 }
441
442
443 static int rs_get_CD (void * ptr) 
444 {
445         /* No Carried Detect in Hardware - just return true */
446         func_exit();
447         return (1);
448 }
449
450 static void rs_shutdown_port (void * ptr) 
451 {
452         struct rs_port *port = ptr; 
453
454         func_enter();
455
456         port->gs.flags &= ~GS_ACTIVE;
457
458         func_exit();
459 }
460
461 static int rs_set_real_termios (void *ptr)
462 {
463         struct rs_port *port = ptr;
464         int t;
465
466         switch (port->gs.baud) {
467                 /* Save some typing work... */
468 #define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
469                 e(300);e(600);e(1200);e(2400);e(4800);e(9600);
470                 e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
471         case 0      :t = -1;
472                 break;
473         default:
474                 /* Can I return "invalid"? */
475                 t = TX3912_UART_CTRL2_B9600;
476                 printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
477                 break;
478         }
479 #undef e
480         if (t >= 0) {
481                 /* Jim: Set Hardware Baud rate - there is some good
482                    code in drivers/char/serial.c */
483
484                 /* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
485                 UartA_Ctrl1 &= 0xf000000f;
486                 UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
487
488 #define CFLAG port->gs.tty->termios->c_cflag
489                 if (C_PARENB(port->gs.tty)) {
490                         if (!C_PARODD(port->gs.tty))
491                                 UartA_Ctrl1 |= SER_EVEN_PARITY;
492                         else
493                                 UartA_Ctrl1 |= SER_ODD_PARITY;
494                 }
495                 if ((CFLAG & CSIZE)==CS6)
496                         printk(KERN_ERR "6 bits not supported\n");
497                 if ((CFLAG & CSIZE)==CS5)
498                         printk(KERN_ERR "5 bits not supported\n");
499                 if ((CFLAG & CSIZE)==CS7)
500                         UartA_Ctrl1 |= SER_SEVEN_BIT;
501                 if (C_CSTOPB(port->gs.tty))
502                         UartA_Ctrl1 |= SER_TWO_STOP;
503
504                 outl(t, port->base + TX3912_UART_CTRL2);
505                 outl(0, port->base + TX3912_UART_DMA_CTRL1);
506                 outl(0, port->base + TX3912_UART_DMA_CTRL2);
507                 UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;
508
509         /* wait until UARTA is stable */
510         while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
511         }
512
513         func_exit ();
514         return 0;
515 }
516
517 static int rs_chars_in_buffer (void * ptr) 
518 {
519         struct rs_port *port = ptr;
520         int scratch;
521
522         scratch = inl(port->base + TX3912_UART_CTRL1);
523
524         return ((scratch & UART_TX_EMPTY) ? 0 : 1);
525 }
526
527 /* ********************************************************************** *
528  *                Here are the routines that actually                     *
529  *               interface with the rest of the system                    *
530  * ********************************************************************** */
531 static int rs_open  (struct tty_struct * tty, struct file * filp)
532 {
533         struct rs_port *port;
534         int retval, line;
535
536         func_enter();
537
538         if (!rs_initialized) {
539                 return -EIO;
540         }
541
542         line = tty->index;
543         rs_dprintk (TX3912_UART_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n", 
544                     (int) current->pid, line, tty, current->tty);
545
546         if ((line < 0) || (line >= TX3912_UART_NPORTS))
547                 return -ENODEV;
548
549         /* Pre-initialized already */
550         port = & rs_ports[line];
551
552         rs_dprintk (TX3912_UART_DEBUG_OPEN, "port = %p\n", port);
553
554         tty->driver_data = port;
555         port->gs.tty = tty;
556         port->gs.count++;
557
558         rs_dprintk (TX3912_UART_DEBUG_OPEN, "starting port\n");
559
560         /*
561          * Start up serial port
562          */
563         retval = gs_init_port(&port->gs);
564         rs_dprintk (TX3912_UART_DEBUG_OPEN, "done gs_init\n");
565         if (retval) {
566                 port->gs.count--;
567                 return retval;
568         }
569
570         port->gs.flags |= GS_ACTIVE;
571
572         rs_dprintk (TX3912_UART_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
573                     port->gs.count);
574         rs_dprintk (TX3912_UART_DEBUG_OPEN, "after inc_use_count\n");
575
576         /* Jim: Initialize port hardware here */
577
578         /* Enable high-priority interrupts for UARTA */
579         IntEnable6 |= INT6_UARTARXINT; 
580         rs_enable_rx_interrupts(&rs_ports[0]); 
581
582         retval = gs_block_til_ready(&port->gs, filp);
583         rs_dprintk (TX3912_UART_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 
584                     retval, port->gs.count);
585
586         if (retval) {
587                 port->gs.count--;
588                 return retval;
589         }
590         /* tty->low_latency = 1; */
591
592         func_exit();
593
594         /* Jim */
595 /*      cli(); */
596
597         return 0;
598
599 }
600
601
602 static int rs_ioctl (struct tty_struct * tty, struct file * filp, 
603                      unsigned int cmd, unsigned long arg)
604 {
605         int rc;
606         struct rs_port *port = tty->driver_data;
607         int ival;
608
609         rc = 0;
610         switch (cmd) {
611         case TIOCGSOFTCAR:
612                 rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
613                               (unsigned int *) arg);
614                 break;
615         case TIOCSSOFTCAR:
616                 if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
617                         tty->termios->c_cflag =
618                                 (tty->termios->c_cflag & ~CLOCAL) |
619                                 (ival ? CLOCAL : 0);
620                 }
621                 break;
622         case TIOCGSERIAL:
623                 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
624                                       sizeof(struct serial_struct))) == 0)
625                         rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
626                 break;
627         case TIOCSSERIAL:
628                 if ((rc = verify_area(VERIFY_READ, (void *) arg,
629                                       sizeof(struct serial_struct))) == 0)
630                         rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
631                 break;
632         default:
633                 rc = -ENOIOCTLCMD;
634                 break;
635         }
636
637         /* func_exit(); */
638         return rc;
639 }
640
641
642 /*
643  * This function is used to send a high-priority XON/XOFF character to
644  * the device
645  */
646 static void rs_send_xchar(struct tty_struct * tty, char ch)
647 {
648         struct rs_port *port = (struct rs_port *)tty->driver_data;
649         func_enter ();
650         
651         port->x_char = ch;
652         if (ch) {
653                 /* Make sure transmit interrupts are on */
654                 rs_enable_tx_interrupts(tty);
655         }
656
657         func_exit();
658 }
659
660
661 /*
662  * ------------------------------------------------------------
663  * rs_throttle()
664  * 
665  * This routine is called by the upper-layer tty layer to signal that
666  * incoming characters should be throttled.
667  * ------------------------------------------------------------
668  */
669 static void rs_throttle(struct tty_struct * tty)
670 {
671 #ifdef TX3912_UART_DEBUG_THROTTLE
672         char    buf[64];
673         
674         printk("throttle %s: %d....\n", tty_name(tty, buf),
675                tty->ldisc.chars_in_buffer(tty));
676 #endif
677
678         func_enter ();
679         
680         if (I_IXOFF(tty))
681                 rs_send_xchar(tty, STOP_CHAR(tty));
682
683         func_exit ();
684 }
685
686 static void rs_unthrottle(struct tty_struct * tty)
687 {
688         struct rs_port *port = (struct rs_port *)tty->driver_data;
689 #ifdef TX3912_UART_DEBUG_THROTTLE
690         char    buf[64];
691         
692         printk("unthrottle %s: %d....\n", tty_name(tty, buf),
693                tty->ldisc.chars_in_buffer(tty));
694 #endif
695
696         func_enter();
697         
698         if (I_IXOFF(tty)) {
699                 if (port->x_char)
700                         port->x_char = 0;
701                 else
702                         rs_send_xchar(tty, START_CHAR(tty));
703         }
704
705         func_exit();
706 }
707
708
709
710
711
712 /* ********************************************************************** *
713  *                    Here are the initialization routines.               *
714  * ********************************************************************** */
715
716 void * ckmalloc (int size)
717 {
718         void *p;
719
720         p = kmalloc(size, GFP_KERNEL);
721         if (p) 
722                 memset(p, 0, size);
723         return p;
724 }
725
726
727
728 static int rs_init_portstructs(void)
729 {
730         struct rs_port *port;
731         int i;
732
733         /* Debugging */
734         func_enter();
735
736         rs_ports          = ckmalloc(TX3912_UART_NPORTS * sizeof (struct rs_port));
737         if (!rs_ports)
738                 return -ENOMEM;
739
740         port = rs_ports;
741         for (i=0; i < TX3912_UART_NPORTS;i++) {
742                 rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
743                 port->gs.magic = SERIAL_MAGIC;
744                 port->gs.close_delay = HZ/2;
745                 port->gs.closing_wait = 30 * HZ;
746                 port->gs.rd = &rs_real_driver;
747 #ifdef NEW_WRITE_LOCKING
748                 port->gs.port_write_sem = MUTEX;
749 #endif
750 #ifdef DECLARE_WAITQUEUE
751                 init_waitqueue_head(&port->gs.open_wait);
752                 init_waitqueue_head(&port->gs.close_wait);
753 #endif
754                 port->base = (i == 0) ? TX3912_UARTA_BASE : TX3912_UARTB_BASE;
755                 port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
756                 rs_dprintk (TX3912_UART_DEBUG_INIT, "base 0x%08lx intshift %d\n",
757                             port->base, port->intshift);
758                 port++;
759         }
760
761         func_exit();
762         return 0;
763 }
764
765 static struct tty_operations rs_ops = {
766         .open   = rs_open,
767         .close = gs_close,
768         .write = gs_write,
769         .put_char = gs_put_char, 
770         .flush_chars = gs_flush_chars,
771         .write_room = gs_write_room,
772         .chars_in_buffer = gs_chars_in_buffer,
773         .flush_buffer = gs_flush_buffer,
774         .ioctl = rs_ioctl,
775         .throttle = rs_throttle,
776         .unthrottle = rs_unthrottle,
777         .set_termios = gs_set_termios,
778         .stop = gs_stop,
779         .start = gs_start,
780         .hangup = gs_hangup,
781 };
782
783 static int rs_init_drivers(void)
784 {
785         int error;
786
787         func_enter();
788
789         rs_driver = alloc_tty_driver(TX3912_UART_NPORTS);
790         if (!rs_driver)
791                 return -ENOMEM;
792         rs_driver->owner = THIS_MODULE;
793         rs_driver->driver_name = "serial";
794         rs_driver->name = "ttyS";
795         rs_driver->major = TTY_MAJOR;
796         rs_driver->minor_start = 64;
797         rs_driver->type = TTY_DRIVER_TYPE_SERIAL;
798         rs_driver->subtype = SERIAL_TYPE_NORMAL;
799         rs_driver->init_termios = tty_std_termios;
800         rs_driver->init_termios.c_cflag =
801                 B115200 | CS8 | CREAD | HUPCL | CLOCAL;
802         tty_set_operations(rs_driver, &rs_ops);
803         if ((error = tty_register_driver(rs_driver))) {
804                 printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
805                        error);
806                 put_tty_driver(rs_driver);
807                 return 1;
808         }
809         return 0;
810 }
811
812
813 static void __init tx3912_rs_init(void)
814 {
815         int rc;
816
817
818         func_enter();
819         rs_dprintk (TX3912_UART_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
820
821         rc = rs_init_portstructs ();
822         rs_init_drivers ();
823         if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
824                         "serial", &rs_ports[0])) {
825                 printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
826                 rc = 0;
827         }
828         if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
829                         "serial", &rs_ports[0])) {
830                 printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
831                 rc = 0;
832         }
833
834         IntEnable6 |= INT6_UARTARXINT; 
835         rs_enable_rx_interrupts(&rs_ports[0]); 
836
837 #ifndef CONFIG_SERIAL_TX3912_CONSOLE
838 {
839         unsigned int scratch = 0;
840
841         /* Setup master clock for UART */
842         scratch = inl(TX3912_CLK_CTRL_BASE);
843         scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
844         scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
845                                 TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
846                         | TX3912_CLK_CTRL_SIBMCLKDIR
847                         | TX3912_CLK_CTRL_ENSIBMCLK
848                         | TX3912_CLK_CTRL_CSERSEL;
849         outl(scratch, TX3912_CLK_CTRL_BASE);
850
851         /* Configure UARTA clock */
852         scratch = inl(TX3912_CLK_CTRL_BASE);
853         scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
854                                 TX3912_CLK_CTRL_CSERDIV_MASK)
855                         | TX3912_CLK_CTRL_ENCSERCLK
856                         | TX3912_CLK_CTRL_ENUARTACLK;
857         outl(scratch, TX3912_CLK_CTRL_BASE);
858                 
859         /* Setup UARTA for 115200,8N1 */
860         outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
861         outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
862         outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
863         outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
864
865         /* Enable UARTA */
866         outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
867         while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
868                 TX3912_UART_CTRL1_UARTON);
869 }
870 #endif
871
872         /* Note: I didn't do anything to enable the second UART */
873         if (rc >= 0) 
874                 rs_initialized++;
875
876         func_exit();
877 }
878 module_init(tx3912_rs_init);
879
880 /*
881  * Begin serial console routines
882  */
883 #ifdef CONFIG_SERIAL_TX3912_CONSOLE
884
885 void serial_outc(unsigned char c)
886 {
887         int i;
888         unsigned long int2;
889         #define BUSY_WAIT 10000
890
891         /*
892          * Turn UARTA interrupts off
893          */
894         int2 = IntEnable2;
895         IntEnable2 &=
896                 ~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
897
898         /*
899          * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
900          * not to be very reliable :-(
901          *
902          * Wait for the Tx register to become empty
903          */
904         for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
905
906         IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
907         UartA_Data = c;
908         for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
909         IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
910
911         IntEnable2 = int2;
912 }
913
914 static void serial_console_write(struct console *co, const char *s,
915                 unsigned count)
916 {
917         unsigned int i;
918
919         for (i = 0; i < count; i++) {
920                 if (*s == '\n')
921                         serial_outc('\r');
922                 serial_outc(*s++);
923         }
924 }
925
926 static struct tty_driver *serial_console_device(struct console *c, int *index)
927 {
928         *index = c->index;
929         return rs_driver;
930 }
931
932 static __init int serial_console_setup(struct console *co, char *options)
933 {
934         unsigned int scratch = 0;
935
936         /* Setup master clock for UART */
937         scratch = inl(TX3912_CLK_CTRL_BASE);
938         scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
939         scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
940                                 TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
941                         | TX3912_CLK_CTRL_SIBMCLKDIR
942                         | TX3912_CLK_CTRL_ENSIBMCLK
943                         | TX3912_CLK_CTRL_CSERSEL;
944         outl(scratch, TX3912_CLK_CTRL_BASE);
945
946         /* Configure UARTA clock */
947         scratch = inl(TX3912_CLK_CTRL_BASE);
948         scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
949                                 TX3912_CLK_CTRL_CSERDIV_MASK)
950                         | TX3912_CLK_CTRL_ENCSERCLK
951                         | TX3912_CLK_CTRL_ENUARTACLK;
952         outl(scratch, TX3912_CLK_CTRL_BASE);
953                 
954         /* Setup UARTA for 115200,8N1 */
955         outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
956         outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
957         outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
958         outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
959
960         /* Enable UARTA */
961         outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
962         while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
963                 TX3912_UART_CTRL1_UARTON);
964
965         return 0;
966 }
967
968 static struct console sercons = {
969         .name     = "ttyS",
970         .write    = serial_console_write,
971         .device   = serial_console_device,
972         .setup    = serial_console_setup,
973         .flags    = CON_PRINTBUFFER,
974         .index    = -1
975 };
976
977 static int __init tx3912_console_init(void)
978 {
979         register_console(&sercons);
980         return 0;
981 }
982 console_initcall(tx3912_console_init);
983
984 #endif