2 * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * Driver support for the on-chip sb1250 dual-channel serial port,
21 * running in asynchronous mode. Also, support for doing a serial console
22 * on one of those ports
24 #include <linux/config.h>
25 #include <linux/types.h>
26 #include <linux/serial.h>
27 #include <linux/interrupt.h>
28 #include <linux/module.h>
29 #include <linux/console.h>
30 #include <linux/kdev_t.h>
31 #include <linux/major.h>
32 #include <linux/termios.h>
33 #include <linux/spinlock.h>
34 #include <linux/irq.h>
35 #include <linux/errno.h>
36 #include <linux/tty.h>
37 #include <linux/sched.h>
38 #include <linux/tty_flip.h>
39 #include <linux/timer.h>
40 #include <linux/init.h>
42 #include <asm/delay.h>
44 #include <asm/uaccess.h>
45 #include <asm/sibyte/swarm.h>
46 #include <asm/sibyte/sb1250_regs.h>
47 #include <asm/sibyte/sb1250_uart.h>
48 #include <asm/sibyte/sb1250_int.h>
49 #include <asm/sibyte/sb1250.h>
52 /* Toggle spewing of debugging output */
55 #define DEFAULT_CFLAGS (CS8 | B115200)
58 #define DUART_INITIALIZED 2
61 #define MIN(a,b) ((a) < (b) ? (a) : (b))
64 #define DUART_MAX_LINE 2
65 char sb1250_duart_present
[DUART_MAX_LINE
] = {1,1};
68 * Still not sure what the termios structures set up here are for,
69 * but we have to supply pointers to them to register the tty driver
71 static struct tty_driver
*sb1250_duart_driver
; //, sb1250_duart_callout_driver;
74 * This lock protects both the open flags for all the uart states as
75 * well as the reference count for the module
77 static spinlock_t open_lock
= SPIN_LOCK_UNLOCKED
;
80 unsigned char outp_buf
[SERIAL_XMIT_SIZE
];
81 unsigned int outp_head
;
82 unsigned int outp_tail
;
83 unsigned int outp_count
;
87 unsigned int last_cflags
;
89 struct tty_struct
*tty
;
101 static uart_state_t uart_states
[DUART_MAX_LINE
];
104 * Inline functions local to this module
108 * In bug 1956, we get glitches that can mess up uart registers. This
109 * "write-mode-1 after any register access" is the accepted
113 static unsigned int last_mode1
[DUART_MAX_LINE
];
116 static inline u32
READ_SERCSR(u32
*addr
, int line
)
118 u32 val
= csr_in32(addr
);
120 csr_out32(last_mode1
[line
], uart_states
[line
].mode_1
);
125 static inline void WRITE_SERCSR(u32 val
, u32
*addr
, int line
)
127 csr_out32(val
, addr
);
129 csr_out32(last_mode1
[line
], uart_states
[line
].mode_1
);
133 static void init_duart_port(uart_state_t
*port
, int line
)
135 if (!(port
->flags
& DUART_INITIALIZED
)) {
137 port
->status
= (u32
*)(IO_SPACE_BASE
| A_DUART_CHANREG(line
, R_DUART_STATUS
));
138 port
->imr
= (u32
*)(IO_SPACE_BASE
| A_DUART_IMRREG(line
));
139 port
->tx_hold
= (u32
*)(IO_SPACE_BASE
| A_DUART_CHANREG(line
, R_DUART_TX_HOLD
));
140 port
->rx_hold
= (u32
*)(IO_SPACE_BASE
| A_DUART_CHANREG(line
, R_DUART_RX_HOLD
));
141 port
->mode_1
= (u32
*)(IO_SPACE_BASE
| A_DUART_CHANREG(line
, R_DUART_MODE_REG_1
));
142 port
->mode_2
= (u32
*)(IO_SPACE_BASE
| A_DUART_CHANREG(line
, R_DUART_MODE_REG_2
));
143 port
->clk_sel
= (u32
*)(IO_SPACE_BASE
| A_DUART_CHANREG(line
, R_DUART_CLK_SEL
));
144 port
->cmd
= (u32
*)(IO_SPACE_BASE
| A_DUART_CHANREG(line
, R_DUART_CMD
));
145 port
->flags
|= DUART_INITIALIZED
;
150 * Mask out the passed interrupt lines at the duart level. This should be
151 * called while holding the associated outp_lock.
153 static inline void duart_mask_ints(unsigned int line
, unsigned int mask
)
155 uart_state_t
*port
= uart_states
+ line
;
156 u64 tmp
= READ_SERCSR(port
->imr
, line
);
157 WRITE_SERCSR(tmp
& ~mask
, port
->imr
, line
);
161 /* Unmask the passed interrupt lines at the duart level */
162 static inline void duart_unmask_ints(unsigned int line
, unsigned int mask
)
164 uart_state_t
*port
= uart_states
+ line
;
165 u64 tmp
= READ_SERCSR(port
->imr
, line
);
166 WRITE_SERCSR(tmp
| mask
, port
->imr
, line
);
169 static inline void transmit_char_pio(uart_state_t
*us
)
171 struct tty_struct
*tty
= us
->tty
;
174 if (spin_trylock(&us
->outp_lock
)) {
176 if (!(READ_SERCSR(us
->status
, us
->line
) & M_DUART_TX_RDY
))
178 if (us
->outp_count
<= 0 || tty
->stopped
|| tty
->hw_stopped
) {
181 WRITE_SERCSR(us
->outp_buf
[us
->outp_head
],
182 us
->tx_hold
, us
->line
);
183 us
->outp_head
= (us
->outp_head
+ 1) & (SERIAL_XMIT_SIZE
-1);
184 if (--us
->outp_count
<= 0)
189 spin_unlock(&us
->outp_lock
);
194 if (!us
->outp_count
|| tty
->stopped
||
195 tty
->hw_stopped
|| blocked
) {
196 us
->flags
&= ~TX_INTEN
;
197 duart_mask_ints(us
->line
, M_DUART_IMR_TX
);
201 (us
->outp_count
< (SERIAL_XMIT_SIZE
/2))) {
203 * We told the discipline at one point that we had no
204 * space, so it went to sleep. Wake it up when we hit
207 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
208 tty
->ldisc
.write_wakeup
)
209 tty
->ldisc
.write_wakeup(tty
);
210 wake_up_interruptible(&tty
->write_wait
);
215 * Generic interrupt handler for both channels. dev_id is a pointer
216 * to the proper uart_states structure, so from that we can derive
217 * which port interrupted
220 static irqreturn_t
duart_int(int irq
, void *dev_id
, struct pt_regs
*regs
)
222 uart_state_t
*us
= (uart_state_t
*)dev_id
;
223 struct tty_struct
*tty
= us
->tty
;
224 unsigned int status
= READ_SERCSR(us
->status
, us
->line
);
227 printk("DUART INT\n");
230 if (status
& M_DUART_RX_RDY
) {
234 if (status
& M_DUART_OVRUN_ERR
)
235 tty_insert_flip_char(tty
, 0, TTY_OVERRUN
);
236 if (status
& M_DUART_PARITY_ERR
) {
237 printk("Parity error!\n");
238 } else if (status
& M_DUART_FRM_ERR
) {
239 printk("Frame error!\n");
242 while (counter
> 0) {
243 if (!(READ_SERCSR(us
->status
, us
->line
) & M_DUART_RX_RDY
))
245 ch
= READ_SERCSR(us
->rx_hold
, us
->line
);
246 if (tty
->flip
.count
< TTY_FLIPBUF_SIZE
) {
247 *tty
->flip
.char_buf_ptr
++ = ch
;
248 *tty
->flip
.flag_buf_ptr
++ = 0;
254 tty_flip_buffer_push(tty
);
257 if (status
& M_DUART_TX_RDY
) {
258 transmit_char_pio(us
);
265 * Actual driver functions
268 /* Return the number of characters we can accomodate in a write at this instant */
269 static int duart_write_room(struct tty_struct
*tty
)
271 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
274 retval
= SERIAL_XMIT_SIZE
- us
->outp_count
;
277 printk("duart_write_room called, returning %i\n", retval
);
283 /* memcpy the data from src to destination, but take extra care if the
284 data is coming from user space */
285 static inline int copy_buf(char *dest
, const char *src
, int size
, int from_user
)
288 (void) copy_from_user(dest
, src
, size
);
290 memcpy(dest
, src
, size
);
296 * Buffer up to count characters from buf to be written. If we don't have
297 * other characters buffered, enable the tx interrupt to start sending
299 static int duart_write(struct tty_struct
* tty
, int from_user
,
300 const unsigned char *buf
, int count
)
308 us
= tty
->driver_data
;
312 printk("duart_write called for %i chars by %i (%s)\n", count
, current
->pid
, current
->comm
);
315 spin_lock_irqsave(&us
->outp_lock
, flags
);
320 t
= SERIAL_XMIT_SIZE
- us
->outp_tail
;
323 t
= SERIAL_XMIT_SIZE
- 1 - us
->outp_count
;
329 if (copy_from_user(us
->outp_buf
+ us
->outp_tail
, buf
, c
)) {
330 spin_unlock_irqrestore(&us
->outp_lock
, flags
);
334 memcpy(us
->outp_buf
+ us
->outp_tail
, buf
, c
);
338 us
->outp_tail
= (us
->outp_tail
+ c
) & (SERIAL_XMIT_SIZE
- 1);
344 spin_unlock_irqrestore(&us
->outp_lock
, flags
);
346 if (us
->outp_count
&& !tty
->stopped
&&
347 !tty
->hw_stopped
&& !(us
->flags
& TX_INTEN
)) {
348 us
->flags
|= TX_INTEN
;
349 duart_unmask_ints(us
->line
, M_DUART_IMR_TX
);
356 /* Buffer one character to be written. If there's not room for it, just drop
357 it on the floor. This is used for echo, among other things */
358 static void duart_put_char(struct tty_struct
*tty
, u_char ch
)
360 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
364 printk("duart_put_char called. Char is %x (%c)\n", (int)ch
, ch
);
367 spin_lock_irqsave(&us
->outp_lock
, flags
);
369 if (us
->outp_count
>= SERIAL_XMIT_SIZE
- 1) {
370 spin_unlock_irqrestore(&us
->outp_lock
, flags
);
374 us
->outp_buf
[us
->outp_tail
] = ch
;
375 us
->outp_tail
= (us
->outp_tail
+ 1) &(SERIAL_XMIT_SIZE
-1);
378 spin_unlock_irqrestore(&us
->outp_lock
, flags
);
381 static void duart_flush_chars(struct tty_struct
* tty
)
387 port
= tty
->driver_data
;
391 if (port
->outp_count
<= 0 || tty
->stopped
|| tty
->hw_stopped
) {
395 port
->flags
|= TX_INTEN
;
396 duart_unmask_ints(port
->line
, M_DUART_IMR_TX
);
399 /* Return the number of characters in the output buffer that have yet to be
401 static int duart_chars_in_buffer(struct tty_struct
*tty
)
403 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
406 retval
= us
->outp_count
;
409 printk("duart_chars_in_buffer returning %i\n", retval
);
414 /* Kill everything we haven't yet shoved into the FIFO. Turn off the
415 transmit interrupt since we've nothing more to transmit */
416 static void duart_flush_buffer(struct tty_struct
*tty
)
418 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
422 printk("duart_flush_buffer called\n");
424 spin_lock_irqsave(&us
->outp_lock
, flags
);
425 us
->outp_head
= us
->outp_tail
= us
->outp_count
= 0;
426 spin_unlock_irqrestore(&us
->outp_lock
, flags
);
428 wake_up_interruptible(&us
->tty
->write_wait
);
429 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
430 tty
->ldisc
.write_wakeup
)
431 tty
->ldisc
.write_wakeup(tty
);
435 /* See sb1250 user manual for details on these registers */
436 static inline void duart_set_cflag(unsigned int line
, unsigned int cflag
)
438 unsigned int mode_reg1
= 0, mode_reg2
= 0;
439 unsigned int clk_divisor
;
440 uart_state_t
*port
= uart_states
+ line
;
442 switch (cflag
& CSIZE
) {
444 mode_reg1
|= V_DUART_BITS_PER_CHAR_7
;
447 /* We don't handle CS5 or CS6...is there a way we're supposed to flag this?
448 right now we just force them to CS8 */
452 if (cflag
& CSTOPB
) {
453 mode_reg2
|= M_DUART_STOP_BIT_LEN_2
;
455 if (!(cflag
& PARENB
)) {
456 mode_reg1
|= V_DUART_PARITY_MODE_NONE
;
458 if (cflag
& PARODD
) {
459 mode_reg1
|= M_DUART_PARITY_TYPE_ODD
;
462 /* Formula for this is (5000000/baud)-1, but we saturate
463 at 12 bits, which means we can't actually do anything less
465 switch (cflag
& CBAUD
) {
468 case B1200
: clk_divisor
= 4095; break;
469 case B1800
: clk_divisor
= 2776; break;
470 case B2400
: clk_divisor
= 2082; break;
471 case B4800
: clk_divisor
= 1040; break;
473 case B9600
: clk_divisor
= 519; break;
474 case B19200
: clk_divisor
= 259; break;
475 case B38400
: clk_divisor
= 129; break;
476 case B57600
: clk_divisor
= 85; break;
477 case B115200
: clk_divisor
= 42; break;
479 WRITE_SERCSR(mode_reg1
, port
->mode_1
, port
->line
);
480 WRITE_SERCSR(mode_reg2
, port
->mode_2
, port
->line
);
481 WRITE_SERCSR(clk_divisor
, port
->clk_sel
, port
->line
);
482 port
->last_cflags
= cflag
;
486 /* Handle notification of a termios change. */
487 static void duart_set_termios(struct tty_struct
*tty
, struct termios
*old
)
489 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
492 printk("duart_set_termios called by %i (%s)\n", current
->pid
, current
->comm
);
494 if (old
&& tty
->termios
->c_cflag
== old
->c_cflag
)
496 duart_set_cflag(us
->line
, tty
->termios
->c_cflag
);
499 static int duart_ioctl(struct tty_struct
*tty
, struct file
* file
,
500 unsigned int cmd
, unsigned long arg
)
502 /* if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
506 printk("Ignoring TIOCMGET\n");
509 printk("Ignoring TIOCMBIS\n");
512 printk("Ignoring TIOCMBIC\n");
515 printk("Ignoring TIOCMSET\n");
518 printk("Ignoring TIOCGSERIAL\n");
521 printk("Ignoring TIOCSSERIAL\n");
524 printk("Ignoring TIOCSERCONFIG\n");
526 case TIOCSERGETLSR
: /* Get line status register */
527 printk("Ignoring TIOCSERGETLSR\n");
530 printk("Ignoring TIOCSERGSTRUCT\n");
533 printk("Ignoring TIOCMIWAIT\n");
536 printk("Ignoring TIOCGICOUNT\n");
539 printk("Ignoring TIOCSERGWILD\n");
542 printk("Ignoring TIOCSERSWILD\n");
547 // printk("Ignoring IOCTL %x from pid %i (%s)\n", cmd, current->pid, current->comm);
550 if ((cmd
!= TIOCGSERIAL
) && (cmd
!= TIOCSSERIAL
) &&
551 (cmd
!= TIOCSERCONFIG
) && (cmd
!= TIOCSERGSTRUCT
) &&
552 (cmd
!= TIOCMIWAIT
) && (cmd
!= TIOCGICOUNT
)) {
553 if (tty
->flags
& (1 << TTY_IO_ERROR
))
565 case TIOCSERGETLSR
: /* Get line status register */
571 /* XXX Implement me! */
572 printk("IOCTL needs implementing: %x\n", cmd
);
575 printk("Unknown ioctl: %x\n", cmd
);
582 static void duart_start(struct tty_struct
*tty
)
584 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
587 printk("duart_start called\n");
590 if (us
->outp_count
&& !(us
->flags
& TX_INTEN
)) {
591 us
->flags
|= TX_INTEN
;
592 duart_unmask_ints(us
->line
, M_DUART_IMR_TX
);
597 static void duart_stop(struct tty_struct
*tty
)
599 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
602 printk("duart_stop called\n");
605 if (us
->outp_count
&& (us
->flags
& TX_INTEN
)) {
606 us
->flags
&= ~TX_INTEN
;
607 duart_mask_ints(us
->line
, M_DUART_IMR_TX
);
611 /* Not sure on the semantics of this; are we supposed to wait until the stuff
612 already in the hardware FIFO drains, or are we supposed to wait until
613 we've drained the output buffer, too? I'm assuming the former, 'cause thats
614 what the other drivers seem to assume
617 static void duart_wait_until_sent(struct tty_struct
*tty
, int timeout
)
619 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
620 unsigned long orig_jiffies
;
622 orig_jiffies
= jiffies
;
624 printk("duart_wait_until_sent(%d)+\n", timeout
);
626 while (!(READ_SERCSR(us
->status
, us
->line
) & M_DUART_TX_EMT
)) {
627 set_current_state(TASK_INTERRUPTIBLE
);
629 if (signal_pending(current
))
631 if (timeout
&& time_after(jiffies
, orig_jiffies
+ timeout
))
635 printk("duart_wait_until_sent()-\n");
640 * duart_hangup() --- called by tty_hangup() when a hangup is signaled.
642 static void duart_hangup(struct tty_struct
*tty
)
644 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
646 duart_flush_buffer(tty
);
652 * Open a tty line. Note that this can be called multiple times, so ->open can
653 * be >1. Only set up the tty struct if this is a "new" open, e.g. ->open was
656 static int duart_open(struct tty_struct
*tty
, struct file
*filp
)
659 unsigned int line
= tty
->index
;
664 if ((line
>= tty
->driver
->num
) || !sb1250_duart_present
[line
]) {
670 printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n",
671 current
->pid
, current
->comm
, tty
, tty
->read_wait
,
675 us
= uart_states
+ line
;
676 tty
->driver_data
= us
;
678 spin_lock_irqsave(&open_lock
, flags
);
681 us
->tty
->termios
->c_cflag
= us
->last_cflags
;
684 us
->flags
&= ~TX_INTEN
;
685 duart_unmask_ints(line
, M_DUART_IMR_RX
);
686 spin_unlock_irqrestore(&open_lock
, flags
);
693 * Close a reference count out. If reference count hits zero, null the
694 * tty, kill the interrupts. The tty_io driver is responsible for making
695 * sure we've cleared out our internal buffers before calling close()
697 static void duart_close(struct tty_struct
*tty
, struct file
*filp
)
699 uart_state_t
*us
= (uart_state_t
*) tty
->driver_data
;
703 printk("duart_close called by %i (%s)\n", current
->pid
, current
->comm
);
706 if (!us
|| !us
->open
)
709 spin_lock_irqsave(&open_lock
, flags
);
710 if (tty_hung_up_p(filp
)) {
712 spin_unlock_irqrestore(&open_lock
, flags
);
716 if (--us
->open
< 0) {
718 printk(KERN_ERR
"duart: bad open count: %d\n", us
->open
);
721 spin_unlock_irqrestore(&open_lock
, flags
);
725 spin_unlock_irqrestore(&open_lock
, flags
);
729 /* Stop accepting input */
730 duart_mask_ints(us
->line
, M_DUART_IMR_RX
);
731 /* Wait for FIFO to drain */
732 while (!(READ_SERCSR(us
->status
, us
->line
) & M_DUART_TX_EMT
))
735 if (tty
->driver
->flush_buffer
)
736 tty
->driver
->flush_buffer(tty
);
737 if (tty
->ldisc
.flush_buffer
)
738 tty
->ldisc
.flush_buffer(tty
);
745 static struct tty_operations duart_ops
= {
747 .close
= duart_close
,
748 .write
= duart_write
,
749 .put_char
= duart_put_char
,
750 .flush_chars
= duart_flush_chars
,
751 .write_room
= duart_write_room
,
752 .chars_in_buffer
= duart_chars_in_buffer
,
753 .flush_buffer
= duart_flush_buffer
,
754 .ioctl
= duart_ioctl
,
755 // .throttle = duart_throttle,
756 // .unthrottle = duart_unthrottle,
757 .set_termios
= duart_set_termios
,
759 .start
= duart_start
,
760 .hangup
= duart_hangup
,
761 .wait_until_sent
= duart_wait_until_sent
,
764 /* Set up the driver and register it, register the 2 1250 UART interrupts. This
765 is called from tty_init, or as a part of the module init */
766 static int __init
sb1250_duart_init(void)
770 sb1250_duart_driver
= alloc_tty_driver(DUART_MAX_LINE
);
771 if (!sb1250_duart_driver
)
774 sb1250_duart_driver
->owner
= THIS_MODULE
;
775 sb1250_duart_driver
->name
= "duart";
776 sb1250_duart_driver
->devfs_name
= "duart/";
777 sb1250_duart_driver
->major
= TTY_MAJOR
;
778 sb1250_duart_driver
->minor_start
= SB1250_DUART_MINOR_BASE
;
779 sb1250_duart_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
780 sb1250_duart_driver
->subtype
= SERIAL_TYPE_NORMAL
;
781 sb1250_duart_driver
->init_termios
= tty_std_termios
;
782 sb1250_duart_driver
->flags
= TTY_DRIVER_REAL_RAW
;
783 tty_set_operations(sb1250_duart_driver
, &duart_ops
);
785 for (i
=0; i
<DUART_MAX_LINE
; i
++) {
786 uart_state_t
*port
= uart_states
+ i
;
788 if (!sb1250_duart_present
[i
])
791 init_duart_port(port
, i
);
792 spin_lock_init(&port
->outp_lock
);
793 duart_mask_ints(i
, M_DUART_IMR_ALL
);
794 if (request_irq(K_INT_UART_0
+i
, duart_int
, 0, "uart", port
)) {
795 panic("Couldn't get uart0 interrupt line");
797 __raw_writeq(M_DUART_RX_EN
|M_DUART_TX_EN
,
798 IO_SPACE_BASE
| A_DUART_CHANREG(i
, R_DUART_CMD
));
799 duart_set_cflag(i
, DEFAULT_CFLAGS
);
802 /* Interrupts are now active, our ISR can be called. */
804 if (tty_register_driver(sb1250_duart_driver
)) {
805 printk(KERN_ERR
"Couldn't register sb1250 duart serial driver\n");
806 put_tty_driver(sb1250_duart_driver
);
812 /* Unload the driver. Unregister stuff, get ready to go away */
813 static void __exit
sb1250_duart_fini(void)
818 local_irq_save(flags
);
819 tty_unregister_driver(sb1250_duart_driver
);
820 put_tty_driver(sb1250_duart_driver
);
822 for (i
=0; i
<DUART_MAX_LINE
; i
++) {
823 if (!sb1250_duart_present
[i
])
825 free_irq(K_INT_UART_0
+i
, &uart_states
[i
]);
826 disable_irq(K_INT_UART_0
+i
);
828 local_irq_restore(flags
);
831 module_init(sb1250_duart_init
);
832 module_exit(sb1250_duart_fini
);
833 MODULE_DESCRIPTION("SB1250 Duart serial driver");
834 MODULE_AUTHOR("Justin Carlson, Broadcom Corp.");
836 #ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE
839 * Serial console stuff. Very basic, polling driver for doing serial
840 * console output. The console_sem is held by the caller, so we
841 * shouldn't be interrupted for more console activity.
842 * XXXKW What about getting interrupted by uart driver activity?
845 void serial_outc(unsigned char c
, int line
)
847 uart_state_t
*port
= uart_states
+ line
;
848 while (!(READ_SERCSR(port
->status
, line
) & M_DUART_TX_RDY
)) ;
849 WRITE_SERCSR(c
, port
->tx_hold
, line
);
850 while (!(READ_SERCSR(port
->status
, port
->line
) & M_DUART_TX_EMT
)) ;
853 static void ser_console_write(struct console
*cons
, const char *s
,
856 int line
= cons
->index
;
857 uart_state_t
*port
= uart_states
+ line
;
860 imr
= READ_SERCSR(port
->imr
, line
);
861 WRITE_SERCSR(0, port
->imr
, line
);
864 serial_outc('\r', line
);
865 serial_outc(*s
++, line
);
867 WRITE_SERCSR(imr
, port
->imr
, line
);
870 static struct tty_driver
*ser_console_device(struct console
*c
, int *index
)
873 return sb1250_duart_driver
;
876 static int ser_console_setup(struct console
*cons
, char *str
)
880 for (i
=0; i
<DUART_MAX_LINE
; i
++) {
881 uart_state_t
*port
= uart_states
+ i
;
883 if (!sb1250_duart_present
[i
])
886 init_duart_port(port
, i
);
888 last_mode1
[i
] = V_DUART_PARITY_MODE_NONE
|V_DUART_BITS_PER_CHAR_8
;
890 WRITE_SERCSR(V_DUART_PARITY_MODE_NONE
|V_DUART_BITS_PER_CHAR_8
,
892 WRITE_SERCSR(M_DUART_STOP_BIT_LEN_1
,
894 WRITE_SERCSR(V_DUART_BAUD_RATE(115200),
900 static struct console sb1250_ser_cons
= {
902 write
: ser_console_write
,
903 device
: ser_console_device
,
904 setup
: ser_console_setup
,
905 flags
: CON_PRINTBUFFER
,
909 static int __init
sb1250_serial_console_init(void)
911 register_console(&sb1250_ser_cons
);
915 console_initcall(sb1250_serial_console_init
);
917 #endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */