2 * drivers/char/serial_tx3912.c
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)
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.
12 * Serial driver for TMPR3912/05 and PR31700 processors
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>
22 #include <linux/slab.h>
23 #include <linux/module.h>
24 #include <linux/delay.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"
34 * Forward declarations for serial routines
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
);
46 * Used by generic serial driver to access hardware
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
,
54 .shutdown_port
= rs_shutdown_port
,
55 .set_real_termios
= rs_set_real_termios
,
56 .chars_in_buffer
= rs_chars_in_buffer
,
60 * Structures and such for TTY sessions and usage counts
62 static struct tty_driver
*rs_driver
;
63 struct rs_port
*rs_ports
;
64 int rs_initialized
= 0;
67 * ----------------------------------------------------------------------
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.
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
79 * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
81 * and look at the resulting assemble code in serial.s.
83 * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
84 * -----------------------------------------------------------------------
86 static inline void receive_char_pio(struct rs_port
*port
)
88 struct tty_struct
*tty
= port
->gs
.tty
;
92 /* While there are characters, get them ... */
94 if (!(inl(port
->base
+ TX3912_UART_CTRL1
) & UART_RX_HOLD_FULL
))
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;
102 udelay(1); /* Allow things to happen - it take a while */
106 printk( "Ugh, looped in receive_char_pio!\n" );
108 tty_flip_buffer_push(tty
);
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
))) {
118 * Now check to see if character should be
119 * ignored, and mask off conditions which
122 if (*status
& port
->ignore_status_mask
) {
125 *status
&= port
->read_status_mask
;
127 if (*status
& INTTYPE(UART_BREAK_INT
)) {
128 rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS
, "handling break....");
129 *tty
->flip
.flag_buf_ptr
= TTY_BREAK
;
131 else if (*status
& INTTYPE(UART_PARITYERR_INT
)) {
132 *tty
->flip
.flag_buf_ptr
= TTY_PARITY
;
134 else if (*status
& INTTYPE(UART_FRAMEERR_INT
)) {
135 *tty
->flip
.flag_buf_ptr
= TTY_FRAME
;
137 if (*status
& INTTYPE(UART_RXOVERRUN_INT
)) {
139 * Overrun is special, since it's
140 * reported immediately, and doesn't
141 * affect the current character
143 if (tty
->flip
.count
< TTY_FLIPBUF_SIZE
) {
145 tty
->flip
.flag_buf_ptr
++;
146 tty
->flip
.char_buf_ptr
++;
147 *tty
->flip
.flag_buf_ptr
= TTY_OVERRUN
;
152 tty
->flip
.flag_buf_ptr
++;
153 tty
->flip
.char_buf_ptr
++;
157 tty_flip_buffer_push(tty
);
161 static inline void transmit_char_pio(struct rs_port
*port
)
163 /* While I'm able to transmit ... */
165 if (!(inl(port
->base
+ TX3912_UART_CTRL1
) & UART_TX_EMPTY
))
167 else if (port
->x_char
) {
168 outb(port
->x_char
, port
->base
+ TX3912_UART_DATA
);
172 else if (port
->gs
.xmit_cnt
<= 0 || port
->gs
.tty
->stopped
||
173 port
->gs
.tty
->hw_stopped
) {
177 outb(port
->gs
.xmit_buf
[port
->gs
.xmit_tail
++],
178 port
->base
+ TX3912_UART_DATA
);
180 port
->gs
.xmit_tail
&= SERIAL_XMIT_SIZE
-1;
181 if (--port
->gs
.xmit_cnt
<= 0) {
185 udelay(10); /* Allow things to happen - it take a while */
188 if (port
->gs
.xmit_cnt
<= 0 || port
->gs
.tty
->stopped
||
189 port
->gs
.tty
->hw_stopped
) {
190 rs_disable_tx_interrupts(port
);
193 if (port
->gs
.xmit_cnt
<= port
->gs
.wakeup_chars
) {
194 tty_wakeup(port
->gs
.tty
);
195 rs_dprintk (TX3912_UART_DEBUG_TRANSMIT
, "Waking up.... ldisc (%d)....\n",
196 port
->gs
.wakeup_chars
);
202 static inline void check_modem_status(struct rs_port
*port
)
204 /* We don't have a carrier detect line - but just respond
205 like we had one anyways so that open() becomes unblocked */
206 wake_up_interruptible(&port
->gs
.open_wait
);
212 * This is the serial driver's interrupt routine (inlined, because
213 * there are two different versions of this, one for each serial port,
214 * differing only by the bits used in interrupt status 2 register)
217 static inline void rs_rx_interrupt(int irq
, void *dev_id
,
218 struct pt_regs
* regs
, int intshift
)
220 struct rs_port
* port
;
221 unsigned long int2status
;
227 port
= (struct rs_port
*)dev_id
;
228 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "rs_interrupt (port %p, shift %d)...", port
, intshift
);
230 /* Get the interrrupts we have enabled */
231 int2status
= IntStatus2
& IntEnable2
;
233 /* Get interrupts in easy to use form */
234 ints
= int2status
>> intshift
;
236 /* Clear any interrupts we might be about to handle */
237 IntClear2
= int2status
& (
238 (INTTYPE(UART_RXOVERRUN_INT
) |
239 INTTYPE(UART_FRAMEERR_INT
) |
240 INTTYPE(UART_BREAK_INT
) |
241 INTTYPE(UART_PARITYERR_INT
) |
242 INTTYPE(UART_RX_INT
)) << intshift
);
244 if (!port
|| !port
->gs
.tty
) {
245 restore_flags(flags
);
249 /* RX Receiver Holding Register Overrun */
250 if (ints
& INTTYPE(UART_RXOVERRUN_INT
)) {
251 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "overrun");
252 port
->icount
.overrun
++;
256 if (ints
& INTTYPE(UART_FRAMEERR_INT
)) {
257 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "frame error");
258 port
->icount
.frame
++;
261 /* Break signal received */
262 if (ints
& INTTYPE(UART_BREAK_INT
)) {
263 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "break");
267 /* RX Parity Error */
268 if (ints
& INTTYPE(UART_PARITYERR_INT
)) {
269 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "parity error");
270 port
->icount
.parity
++;
273 /* Receive byte (non-DMA) */
274 if (ints
& INTTYPE(UART_RX_INT
)) {
275 receive_char_pio(port
);
278 restore_flags(flags
);
280 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "end.\n");
283 static inline void rs_tx_interrupt(int irq
, void *dev_id
,
284 struct pt_regs
* regs
, int intshift
)
286 struct rs_port
* port
;
287 unsigned long int2status
;
293 port
= (struct rs_port
*)dev_id
;
294 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "rs_interrupt (port %p, shift %d)...", port
, intshift
);
296 /* Get the interrrupts we have enabled */
297 int2status
= IntStatus2
& IntEnable2
;
299 if (!port
|| !port
->gs
.tty
) {
300 restore_flags(flags
);
304 /* Get interrupts in easy to use form */
305 ints
= int2status
>> intshift
;
307 /* Clear any interrupts we might be about to handle */
308 IntClear2
= int2status
& (
309 (INTTYPE(UART_TX_INT
) |
310 INTTYPE(UART_EMPTY_INT
) |
311 INTTYPE(UART_TXOVERRUN_INT
)) << intshift
);
313 /* TX holding register empty, so transmit byte (non-DMA) */
314 if (ints
& (INTTYPE(UART_TX_INT
) | INTTYPE(UART_EMPTY_INT
))) {
315 transmit_char_pio(port
);
318 /* TX Transmit Holding Register Overrun (shouldn't happen) */
319 if (ints
& INTTYPE(UART_TXOVERRUN_INT
)) {
320 printk ( "rs: TX overrun\n");
324 check_modem_status();
327 restore_flags(flags
);
329 rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS
, "end.\n");
332 static void rs_rx_interrupt_uarta(int irq
, void *dev_id
,
333 struct pt_regs
* regs
)
335 rs_rx_interrupt(irq
, dev_id
, regs
, UARTA_SHIFT
);
338 static void rs_tx_interrupt_uarta(int irq
, void *dev_id
,
339 struct pt_regs
* regs
)
341 rs_tx_interrupt(irq
, dev_id
, regs
, UARTA_SHIFT
);
345 ***********************************************************************
346 * Here are the routines that actually *
347 * interface with the generic_serial driver *
348 ***********************************************************************
350 static void rs_disable_tx_interrupts (void * ptr
)
352 struct rs_port
*port
= ptr
;
356 port
->gs
.flags
&= ~GS_TX_INTEN
;
358 IntEnable2
&= ~((INTTYPE(UART_TX_INT
) |
359 INTTYPE(UART_EMPTY_INT
) |
360 INTTYPE(UART_TXOVERRUN_INT
)) << port
->intshift
);
362 IntClear2
= (INTTYPE(UART_TX_INT
) |
363 INTTYPE(UART_EMPTY_INT
) |
364 INTTYPE(UART_TXOVERRUN_INT
)) << port
->intshift
;
366 restore_flags(flags
);
369 static void rs_enable_tx_interrupts (void * ptr
)
371 struct rs_port
*port
= ptr
;
376 IntClear2
= (INTTYPE(UART_TX_INT
) |
377 INTTYPE(UART_EMPTY_INT
) |
378 INTTYPE(UART_TXOVERRUN_INT
)) << port
->intshift
;
380 IntEnable2
|= (INTTYPE(UART_TX_INT
) |
381 INTTYPE(UART_EMPTY_INT
) |
382 INTTYPE(UART_TXOVERRUN_INT
)) << port
->intshift
;
384 /* Send a char to start TX interrupts happening */
385 transmit_char_pio(port
);
387 restore_flags(flags
);
390 static void rs_disable_rx_interrupts (void * ptr
)
392 struct rs_port
*port
= ptr
;
397 IntEnable2
&= ~((INTTYPE(UART_RX_INT
) |
398 INTTYPE(UART_RXOVERRUN_INT
) |
399 INTTYPE(UART_FRAMEERR_INT
) |
400 INTTYPE(UART_BREAK_INT
) |
401 INTTYPE(UART_PARITYERR_INT
)) << port
->intshift
);
403 IntClear2
= (INTTYPE(UART_RX_INT
) |
404 INTTYPE(UART_RXOVERRUN_INT
) |
405 INTTYPE(UART_FRAMEERR_INT
) |
406 INTTYPE(UART_BREAK_INT
) |
407 INTTYPE(UART_PARITYERR_INT
)) << port
->intshift
;
409 restore_flags(flags
);
412 static void rs_enable_rx_interrupts (void * ptr
)
414 struct rs_port
*port
= ptr
;
419 IntEnable2
|= (INTTYPE(UART_RX_INT
) |
420 INTTYPE(UART_RXOVERRUN_INT
) |
421 INTTYPE(UART_FRAMEERR_INT
) |
422 INTTYPE(UART_BREAK_INT
) |
423 INTTYPE(UART_PARITYERR_INT
)) << port
->intshift
;
425 /* Empty the input buffer - apparently this is *vital* */
426 while (inl(port
->base
+ TX3912_UART_CTRL1
) & UART_RX_HOLD_FULL
) {
427 inb(port
->base
+ TX3912_UART_DATA
);
430 IntClear2
= (INTTYPE(UART_RX_INT
) |
431 INTTYPE(UART_RXOVERRUN_INT
) |
432 INTTYPE(UART_FRAMEERR_INT
) |
433 INTTYPE(UART_BREAK_INT
) |
434 INTTYPE(UART_PARITYERR_INT
)) << port
->intshift
;
436 restore_flags(flags
);
440 static int rs_get_CD (void * ptr
)
442 /* No Carried Detect in Hardware - just return true */
447 static void rs_shutdown_port (void * ptr
)
449 struct rs_port
*port
= ptr
;
453 port
->gs
.flags
&= ~GS_ACTIVE
;
458 static int rs_set_real_termios (void *ptr
)
460 struct rs_port
*port
= ptr
;
463 switch (port
->gs
.baud
) {
464 /* Save some typing work... */
465 #define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
466 e(300);e(600);e(1200);e(2400);e(4800);e(9600);
467 e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
471 /* Can I return "invalid"? */
472 t
= TX3912_UART_CTRL2_B9600
;
473 printk (KERN_INFO
"rs: unsupported baud rate: %d.\n", port
->gs
.baud
);
478 /* Jim: Set Hardware Baud rate - there is some good
479 code in drivers/char/serial.c */
481 /* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
482 UartA_Ctrl1
&= 0xf000000f;
483 UartA_Ctrl1
&= ~(UART_DIS_TXD
| SER_SEVEN_BIT
| SER_EVEN_PARITY
| SER_TWO_STOP
);
485 #define CFLAG port->gs.tty->termios->c_cflag
486 if (C_PARENB(port
->gs
.tty
)) {
487 if (!C_PARODD(port
->gs
.tty
))
488 UartA_Ctrl1
|= SER_EVEN_PARITY
;
490 UartA_Ctrl1
|= SER_ODD_PARITY
;
492 if ((CFLAG
& CSIZE
)==CS6
)
493 printk(KERN_ERR
"6 bits not supported\n");
494 if ((CFLAG
& CSIZE
)==CS5
)
495 printk(KERN_ERR
"5 bits not supported\n");
496 if ((CFLAG
& CSIZE
)==CS7
)
497 UartA_Ctrl1
|= SER_SEVEN_BIT
;
498 if (C_CSTOPB(port
->gs
.tty
))
499 UartA_Ctrl1
|= SER_TWO_STOP
;
501 outl(t
, port
->base
+ TX3912_UART_CTRL2
);
502 outl(0, port
->base
+ TX3912_UART_DMA_CTRL1
);
503 outl(0, port
->base
+ TX3912_UART_DMA_CTRL2
);
504 UartA_Ctrl1
|= TX3912_UART_CTRL1_UARTON
;
506 /* wait until UARTA is stable */
507 while (~UartA_Ctrl1
& TX3912_UART_CTRL1_UARTON
);
514 static int rs_chars_in_buffer (void * ptr
)
516 struct rs_port
*port
= ptr
;
519 scratch
= inl(port
->base
+ TX3912_UART_CTRL1
);
521 return ((scratch
& UART_TX_EMPTY
) ? 0 : 1);
524 /* ********************************************************************** *
525 * Here are the routines that actually *
526 * interface with the rest of the system *
527 * ********************************************************************** */
528 static int rs_open (struct tty_struct
* tty
, struct file
* filp
)
530 struct rs_port
*port
;
535 if (!rs_initialized
) {
540 rs_dprintk (TX3912_UART_DEBUG_OPEN
, "%d: opening line %d. tty=%p ctty=%p)\n",
541 (int) current
->pid
, line
, tty
, current
->tty
);
543 if ((line
< 0) || (line
>= TX3912_UART_NPORTS
))
546 /* Pre-initialized already */
547 port
= & rs_ports
[line
];
549 rs_dprintk (TX3912_UART_DEBUG_OPEN
, "port = %p\n", port
);
551 tty
->driver_data
= port
;
555 rs_dprintk (TX3912_UART_DEBUG_OPEN
, "starting port\n");
558 * Start up serial port
560 retval
= gs_init_port(&port
->gs
);
561 rs_dprintk (TX3912_UART_DEBUG_OPEN
, "done gs_init\n");
567 port
->gs
.flags
|= GS_ACTIVE
;
569 rs_dprintk (TX3912_UART_DEBUG_OPEN
, "before inc_use_count (count=%d.\n",
571 rs_dprintk (TX3912_UART_DEBUG_OPEN
, "after inc_use_count\n");
573 /* Jim: Initialize port hardware here */
575 /* Enable high-priority interrupts for UARTA */
576 IntEnable6
|= INT6_UARTARXINT
;
577 rs_enable_rx_interrupts(&rs_ports
[0]);
579 retval
= gs_block_til_ready(&port
->gs
, filp
);
580 rs_dprintk (TX3912_UART_DEBUG_OPEN
, "Block til ready returned %d. Count=%d\n",
581 retval
, port
->gs
.count
);
587 /* tty->low_latency = 1; */
599 static int rs_ioctl (struct tty_struct
* tty
, struct file
* filp
,
600 unsigned int cmd
, unsigned long arg
)
603 struct rs_port
*port
= tty
->driver_data
;
609 rc
= put_user(((tty
->termios
->c_cflag
& CLOCAL
) ? 1 : 0),
610 (unsigned int *) arg
);
613 if ((rc
= get_user(ival
, (unsigned int *) arg
)) == 0) {
614 tty
->termios
->c_cflag
=
615 (tty
->termios
->c_cflag
& ~CLOCAL
) |
620 if ((rc
= verify_area(VERIFY_WRITE
, (void *) arg
,
621 sizeof(struct serial_struct
))) == 0)
622 rc
= gs_getserial(&port
->gs
, (struct serial_struct
*) arg
);
625 if ((rc
= verify_area(VERIFY_READ
, (void *) arg
,
626 sizeof(struct serial_struct
))) == 0)
627 rc
= gs_setserial(&port
->gs
, (struct serial_struct
*) arg
);
640 * This function is used to send a high-priority XON/XOFF character to
643 static void rs_send_xchar(struct tty_struct
* tty
, char ch
)
645 struct rs_port
*port
= (struct rs_port
*)tty
->driver_data
;
650 /* Make sure transmit interrupts are on */
651 rs_enable_tx_interrupts(tty
);
659 * ------------------------------------------------------------
662 * This routine is called by the upper-layer tty layer to signal that
663 * incoming characters should be throttled.
664 * ------------------------------------------------------------
666 static void rs_throttle(struct tty_struct
* tty
)
668 #ifdef TX3912_UART_DEBUG_THROTTLE
671 printk("throttle %s: %d....\n", tty_name(tty
, buf
),
672 tty
->ldisc
.chars_in_buffer(tty
));
678 rs_send_xchar(tty
, STOP_CHAR(tty
));
683 static void rs_unthrottle(struct tty_struct
* tty
)
685 struct rs_port
*port
= (struct rs_port
*)tty
->driver_data
;
686 #ifdef TX3912_UART_DEBUG_THROTTLE
689 printk("unthrottle %s: %d....\n", tty_name(tty
, buf
),
690 tty
->ldisc
.chars_in_buffer(tty
));
699 rs_send_xchar(tty
, START_CHAR(tty
));
709 /* ********************************************************************** *
710 * Here are the initialization routines. *
711 * ********************************************************************** */
713 void * ckmalloc (int size
)
717 p
= kmalloc(size
, GFP_KERNEL
);
725 static int rs_init_portstructs(void)
727 struct rs_port
*port
;
733 rs_ports
= ckmalloc(TX3912_UART_NPORTS
* sizeof (struct rs_port
));
738 for (i
=0; i
< TX3912_UART_NPORTS
;i
++) {
739 rs_dprintk (TX3912_UART_DEBUG_INIT
, "initing port %d\n", i
);
740 port
->gs
.magic
= SERIAL_MAGIC
;
741 port
->gs
.close_delay
= HZ
/2;
742 port
->gs
.closing_wait
= 30 * HZ
;
743 port
->gs
.rd
= &rs_real_driver
;
744 #ifdef NEW_WRITE_LOCKING
745 port
->gs
.port_write_sem
= MUTEX
;
747 #ifdef DECLARE_WAITQUEUE
748 init_waitqueue_head(&port
->gs
.open_wait
);
749 init_waitqueue_head(&port
->gs
.close_wait
);
751 port
->base
= (i
== 0) ? TX3912_UARTA_BASE
: TX3912_UARTB_BASE
;
752 port
->intshift
= (i
== 0) ? UARTA_SHIFT
: UARTB_SHIFT
;
753 rs_dprintk (TX3912_UART_DEBUG_INIT
, "base 0x%08lx intshift %d\n",
754 port
->base
, port
->intshift
);
762 static struct tty_operations rs_ops
= {
766 .put_char
= gs_put_char
,
767 .flush_chars
= gs_flush_chars
,
768 .write_room
= gs_write_room
,
769 .chars_in_buffer
= gs_chars_in_buffer
,
770 .flush_buffer
= gs_flush_buffer
,
772 .throttle
= rs_throttle
,
773 .unthrottle
= rs_unthrottle
,
774 .set_termios
= gs_set_termios
,
780 static int rs_init_drivers(void)
786 rs_driver
= alloc_tty_driver(TX3912_UART_NPORTS
);
789 rs_driver
->owner
= THIS_MODULE
;
790 rs_driver
->driver_name
= "serial";
791 rs_driver
->name
= "ttyS";
792 rs_driver
->major
= TTY_MAJOR
;
793 rs_driver
->minor_start
= 64;
794 rs_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
795 rs_driver
->subtype
= SERIAL_TYPE_NORMAL
;
796 rs_driver
->init_termios
= tty_std_termios
;
797 rs_driver
->init_termios
.c_cflag
=
798 B115200
| CS8
| CREAD
| HUPCL
| CLOCAL
;
799 tty_set_operations(rs_driver
, &rs_ops
);
800 if ((error
= tty_register_driver(rs_driver
))) {
801 printk(KERN_ERR
"Couldn't register serial driver, error = %d\n",
803 put_tty_driver(rs_driver
);
810 static void __init
tx3912_rs_init(void)
816 rs_dprintk (TX3912_UART_DEBUG_INIT
, "Initing serial module... (rs_debug=%d)\n", rs_debug
);
818 rc
= rs_init_portstructs ();
820 if (request_irq(2, rs_tx_interrupt_uarta
, SA_SHIRQ
| SA_INTERRUPT
,
821 "serial", &rs_ports
[0])) {
822 printk(KERN_ERR
"rs: Cannot allocate irq for UARTA.\n");
825 if (request_irq(3, rs_rx_interrupt_uarta
, SA_SHIRQ
| SA_INTERRUPT
,
826 "serial", &rs_ports
[0])) {
827 printk(KERN_ERR
"rs: Cannot allocate irq for UARTA.\n");
831 IntEnable6
|= INT6_UARTARXINT
;
832 rs_enable_rx_interrupts(&rs_ports
[0]);
834 #ifndef CONFIG_SERIAL_TX3912_CONSOLE
836 unsigned int scratch
= 0;
838 /* Setup master clock for UART */
839 scratch
= inl(TX3912_CLK_CTRL_BASE
);
840 scratch
&= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK
;
841 scratch
|= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT
) &
842 TX3912_CLK_CTRL_SIBMCLKDIV_MASK
)
843 | TX3912_CLK_CTRL_SIBMCLKDIR
844 | TX3912_CLK_CTRL_ENSIBMCLK
845 | TX3912_CLK_CTRL_CSERSEL
;
846 outl(scratch
, TX3912_CLK_CTRL_BASE
);
848 /* Configure UARTA clock */
849 scratch
= inl(TX3912_CLK_CTRL_BASE
);
850 scratch
|= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT
) &
851 TX3912_CLK_CTRL_CSERDIV_MASK
)
852 | TX3912_CLK_CTRL_ENCSERCLK
853 | TX3912_CLK_CTRL_ENUARTACLK
;
854 outl(scratch
, TX3912_CLK_CTRL_BASE
);
856 /* Setup UARTA for 115200,8N1 */
857 outl(0, TX3912_UARTA_BASE
+ TX3912_UART_CTRL1
);
858 outl(TX3912_UART_CTRL2_B115200
, TX3912_UARTA_BASE
+ TX3912_UART_CTRL2
);
859 outl(0, TX3912_UARTA_BASE
+ TX3912_UART_DMA_CTRL1
);
860 outl(0, TX3912_UARTA_BASE
+ TX3912_UART_DMA_CTRL2
);
863 outl(TX3912_UART_CTRL1_ENUART
, TX3912_UARTA_BASE
+ TX3912_UART_CTRL1
);
864 while (~inl(TX3912_UARTA_BASE
+ TX3912_UART_CTRL1
) &
865 TX3912_UART_CTRL1_UARTON
);
869 /* Note: I didn't do anything to enable the second UART */
875 module_init(tx3912_rs_init
);
878 * Begin serial console routines
880 #ifdef CONFIG_SERIAL_TX3912_CONSOLE
882 void serial_outc(unsigned char c
)
886 #define BUSY_WAIT 10000
889 * Turn UARTA interrupts off
893 ~(INT2_UARTATXINT
| INT2_UARTATXOVERRUN
| INT2_UARTAEMPTY
);
896 * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
897 * not to be very reliable :-(
899 * Wait for the Tx register to become empty
901 for (i
= 0; !(IntStatus2
& INT2_UARTATXINT
) && (i
< BUSY_WAIT
); i
++);
903 IntClear2
= INT2_UARTATXINT
| INT2_UARTATXOVERRUN
| INT2_UARTAEMPTY
;
905 for (i
= 0; !(IntStatus2
& INT2_UARTATXINT
) && (i
< BUSY_WAIT
); i
++);
906 IntClear2
= INT2_UARTATXINT
| INT2_UARTATXOVERRUN
| INT2_UARTAEMPTY
;
911 static void serial_console_write(struct console
*co
, const char *s
,
916 for (i
= 0; i
< count
; i
++) {
923 static struct tty_driver
*serial_console_device(struct console
*c
, int *index
)
929 static __init
int serial_console_setup(struct console
*co
, char *options
)
931 unsigned int scratch
= 0;
933 /* Setup master clock for UART */
934 scratch
= inl(TX3912_CLK_CTRL_BASE
);
935 scratch
&= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK
;
936 scratch
|= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT
) &
937 TX3912_CLK_CTRL_SIBMCLKDIV_MASK
)
938 | TX3912_CLK_CTRL_SIBMCLKDIR
939 | TX3912_CLK_CTRL_ENSIBMCLK
940 | TX3912_CLK_CTRL_CSERSEL
;
941 outl(scratch
, TX3912_CLK_CTRL_BASE
);
943 /* Configure UARTA clock */
944 scratch
= inl(TX3912_CLK_CTRL_BASE
);
945 scratch
|= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT
) &
946 TX3912_CLK_CTRL_CSERDIV_MASK
)
947 | TX3912_CLK_CTRL_ENCSERCLK
948 | TX3912_CLK_CTRL_ENUARTACLK
;
949 outl(scratch
, TX3912_CLK_CTRL_BASE
);
951 /* Setup UARTA for 115200,8N1 */
952 outl(0, TX3912_UARTA_BASE
+ TX3912_UART_CTRL1
);
953 outl(TX3912_UART_CTRL2_B115200
, TX3912_UARTA_BASE
+ TX3912_UART_CTRL2
);
954 outl(0, TX3912_UARTA_BASE
+ TX3912_UART_DMA_CTRL1
);
955 outl(0, TX3912_UARTA_BASE
+ TX3912_UART_DMA_CTRL2
);
958 outl(TX3912_UART_CTRL1_ENUART
, TX3912_UARTA_BASE
+ TX3912_UART_CTRL1
);
959 while (~inl(TX3912_UARTA_BASE
+ TX3912_UART_CTRL1
) &
960 TX3912_UART_CTRL1_UARTON
);
965 static struct console sercons
= {
967 .write
= serial_console_write
,
968 .device
= serial_console_device
,
969 .setup
= serial_console_setup
,
970 .flags
= CON_PRINTBUFFER
,
974 static int __init
tx3912_console_init(void)
976 register_console(&sercons
);
979 console_initcall(tx3912_console_init
);