3 Copyright 2002 Broadcom Corp. All Rights Reserved.
5 This program is free software; you can distribute it and/or modify it
6 under the terms of the GNU General Public License (Version 2) as
7 published by the Free Software Foundation.
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
20 /* Description: Serial port driver for the BCM963XX. */
22 #define CARDNAME "bcm963xx_serial driver"
24 #define VER_STR CARDNAME " v" VERSION "\n"
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/version.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/interrupt.h>
33 #include <linux/spinlock.h>
35 /* for definition of struct console */
36 #include <linux/console.h>
37 #include <linux/tty.h>
38 #include <linux/tty_flip.h>
39 #include <linux/serial.h>
40 #include <linux/serialP.h>
41 #include <asm/uaccess.h>
45 #include <bcm_map_part.h>
48 static DEFINE_SPINLOCK(bcm963xx_serial_lock);
50 extern void _putc(char);
51 extern void _puts(const char *);
53 typedef struct bcm_serial {
60 unsigned short close_delay;
61 unsigned short closing_wait;
62 unsigned short line; /* port/line number */
63 unsigned short cflags; /* line configuration flag */
64 unsigned short x_char; /* xon/xoff character */
65 unsigned short read_status_mask; /* mask for read condition */
66 unsigned short ignore_status_mask; /* mask for ignore condition */
67 unsigned long event; /* mask used in BH */
68 int xmit_head; /* Position of the head */
69 int xmit_tail; /* Position of the tail */
70 int xmit_cnt; /* Count of the chars in the buffer */
71 int count; /* indicates how many times it has been opened */
74 struct async_icount icount; /* keep track of things ... */
75 struct tty_struct *tty; /* tty associated */
76 struct termios normal_termios;
78 wait_queue_head_t open_wait;
79 wait_queue_head_t close_wait;
81 long session; /* Session of opening process */
82 long pgrp; /* pgrp of opening process */
84 unsigned char is_initialized;
88 /*---------------------------------------------------------------------*/
89 /* Define bits in the Interrupt Enable register */
90 /*---------------------------------------------------------------------*/
91 /* Enable receive interrupt */
92 #define RXINT (RXFIFONE|RXOVFERR)
94 /* Enable transmit interrupt */
95 #define TXINT (TXFIFOEMT|TXUNDERR|TXOVFERR)
97 /* Enable receiver line status interrupt */
98 #define LSINT (RXBRK|RXPARERR|RXFRAMERR)
100 #define BCM_NUM_UARTS 1
102 #define BD_BCM63XX_TIMER_CLOCK_INPUT (FPERIPH)
105 static struct bcm_serial multi[BCM_NUM_UARTS];
106 static struct bcm_serial *lines[BCM_NUM_UARTS];
107 static struct tty_driver *serial_driver;
108 static struct termios *serial_termios[BCM_NUM_UARTS];
109 static struct termios *serial_termios_locked[BCM_NUM_UARTS];
112 static void bcm_stop (struct tty_struct *tty);
113 static void bcm_start (struct tty_struct *tty);
114 static inline void receive_chars (struct bcm_serial * info);
115 static int startup (struct bcm_serial *info);
116 static void shutdown (struct bcm_serial * info);
117 static void change_speed( volatile Uart *pUart, tcflag_t cFlag );
118 static void bcm63xx_cons_flush_chars (struct tty_struct *tty);
119 static int bcm63xx_cons_write (struct tty_struct *tty,
120 const unsigned char *buf, int count);
121 static int bcm63xx_cons_write_room (struct tty_struct *tty);
122 static int bcm_chars_in_buffer (struct tty_struct *tty);
123 static void bcm_flush_buffer (struct tty_struct *tty);
124 static void bcm_throttle (struct tty_struct *tty);
125 static void bcm_unthrottle (struct tty_struct *tty);
126 static void bcm_send_xchar (struct tty_struct *tty, char ch);
127 static int get_serial_info(struct bcm_serial *info, struct serial_struct *retinfo);
128 static int set_serial_info (struct bcm_serial *info, struct serial_struct *new_info);
129 static int get_lsr_info (struct bcm_serial *info, unsigned int *value);
130 static void send_break (struct bcm_serial *info, int duration);
131 static int bcm_ioctl (struct tty_struct * tty, struct file * file,
132 unsigned int cmd, unsigned long arg);
133 static void bcm_set_termios (struct tty_struct *tty, struct termios *old_termios);
134 static void bcm63xx_cons_close (struct tty_struct *tty, struct file *filp);
135 static void bcm_hangup (struct tty_struct *tty);
136 static int block_til_ready (struct tty_struct *tty, struct file *filp, struct bcm_serial *info);
137 static int bcm63xx_cons_open (struct tty_struct * tty, struct file * filp);
138 static int __init bcm63xx_serialinit(void);
142 * ------------------------------------------------------------
143 * rs_stop () and rs_start ()
145 * These routines are called before setting or resetting
146 * tty->stopped. They enable or disable transmitter interrupts,
148 * ------------------------------------------------------------
150 static void bcm_stop (struct tty_struct *tty)
154 static void bcm_start (struct tty_struct *tty)
156 _puts(CARDNAME " Start\n");
160 * ------------------------------------------------------------
163 * This routine deals with inputs from any lines.
164 * ------------------------------------------------------------
166 static inline void receive_chars (struct bcm_serial * info)
168 struct tty_struct *tty = 0;
169 struct async_icount * icount;
171 unsigned short status, tmp;
173 while ((status = info->port->intStatus) & RXINT)
175 char flag_char = TTY_NORMAL;
177 if (status & RXFIFONE)
178 ch = info->port->Data; // Read the character
179 tty = info->tty; /* now tty points to the proper dev */
180 icount = &info->icount;
183 if (!tty_buffer_request_room(tty, 1))
188 flag_char = TTY_BREAK;
191 // keep track of the statistics
192 if (status & (RXFRAMERR | RXPARERR | RXOVFERR))
194 if (status & RXPARERR) /* parity error */
197 if (status & RXFRAMERR) /* frame error */
199 if (status & RXOVFERR)
201 // Overflow. Reset the RX FIFO
202 info->port->fifoctl |= RSTRXFIFOS;
205 // check to see if we should ignore the character
206 // and mask off conditions that should be ignored
207 if (status & info->ignore_status_mask)
213 // Mask off the error conditions we want to ignore
214 tmp = status & info->read_status_mask;
217 flag_char = TTY_PARITY;
222 flag_char = TTY_FRAME;
226 tty_insert_flip_char(tty, ch, flag_char);
228 flag_char = TTY_OVERRUN;
229 if (!tty_buffer_request_room(tty, 1))
233 tty_insert_flip_char(tty, ch, flag_char);
236 tty_flip_buffer_push(tty);
237 tty_schedule_flip(tty);
243 * ------------------------------------------------------------
246 * this is the main interrupt routine for the chip.
247 * It deals with the multiple ports.
248 * ------------------------------------------------------------
250 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
251 static irqreturn_t bcm_interrupt (int irq, void * dev)
253 static void bcm_interrupt (int irq, void * dev, struct pt_regs * regs)
256 struct bcm_serial * info = lines[0];
259 /* get pending interrupt flags from UART */
261 /* Mask with only the serial interrupts that are enabled */
262 intStat = info->port->intStatus & info->port->intMask;
266 receive_chars (info);
269 info->port->intStatus = TXINT;
270 else /* don't know what it was, so let's mask it */
271 info->port->intMask &= ~intStat;
273 intStat = info->port->intStatus & info->port->intMask;
276 // Clear the interrupt
277 BcmHalInterruptEnable (INTERRUPT_ID_UART);
278 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
284 * -------------------------------------------------------------------
287 * various initialization tasks
288 * -------------------------------------------------------------------
290 static int startup (struct bcm_serial *info)
292 // Port is already started...
297 * -------------------------------------------------------------------
300 * This routine will shutdown a serial port; interrupts are disabled, and
301 * DTR is dropped if the hangup on close termio flag is on.
302 * -------------------------------------------------------------------
304 static void shutdown (struct bcm_serial * info)
307 if (!info->is_initialized)
310 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
312 info->port->control &= ~(BRGEN|TXEN|RXEN);
314 set_bit (TTY_IO_ERROR, &info->tty->flags);
315 info->is_initialized = 0;
317 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
320 * -------------------------------------------------------------------
323 * Set the baud rate, character size, parity and stop bits.
324 * -------------------------------------------------------------------
326 static void change_speed( volatile Uart *pUart, tcflag_t cFlag )
328 unsigned long ulFlags, ulBaud, ulClockFreqHz, ulTmp;
330 spin_lock_irqsave(&bcm963xx_serial_lock, ulFlags);
331 switch( cFlag & (CBAUD | CBAUDEX) )
389 /* Calculate buad rate. */
390 ulClockFreqHz = BD_BCM63XX_TIMER_CLOCK_INPUT;
391 ulTmp = (ulClockFreqHz / ulBaud) / 16;
393 ulTmp /= 2; /* Rounding up, so sub is already accounted for */
395 ulTmp = (ulTmp / 2) - 1; /* Rounding down so we must sub 1 */
396 pUart->baudword = ulTmp;
398 /* Set character size, stop bits and parity. */
399 switch( cFlag & CSIZE )
402 ulTmp = BITS5SYM; /* select transmit 5 bit data size */
405 ulTmp = BITS6SYM; /* select transmit 6 bit data size */
408 ulTmp = BITS7SYM; /* select transmit 7 bit data size */
411 ulTmp = BITS8SYM; /* select transmit 8 bit data size */
415 ulTmp |= TWOSTOP; /* select 2 stop bits */
417 ulTmp |= ONESTOP; /* select one stop bit */
419 /* Write these values into the config reg. */
420 pUart->config = ulTmp;
421 pUart->control &= ~(RXPARITYEN | TXPARITYEN | RXPARITYEVEN | TXPARITYEVEN);
422 switch( cFlag & (PARENB | PARODD) )
425 pUart->control |= RXPARITYEN | TXPARITYEN;
428 pUart->control |= RXPARITYEN | TXPARITYEN | RXPARITYEVEN | TXPARITYEVEN;
435 /* Reset and flush uart */
436 pUart->fifoctl = RSTTXFIFOS | RSTRXFIFOS;
437 spin_unlock_irqrestore(&bcm963xx_serial_lock, ulFlags);
442 * -------------------------------------------------------------------
445 * Nothing to flush. Polled I/O is used.
446 * -------------------------------------------------------------------
448 static void bcm63xx_cons_flush_chars (struct tty_struct *tty)
454 * -------------------------------------------------------------------
455 * bcm63xx_cons_write ()
457 * Main output routine using polled I/O.
458 * -------------------------------------------------------------------
460 static int bcm63xx_cons_write (struct tty_struct *tty,
461 const unsigned char *buf, int count)
465 for (c = 0; c < count; c++)
471 * -------------------------------------------------------------------
472 * bcm63xx_cons_write_room ()
474 * Compute the amount of space available for writing.
475 * -------------------------------------------------------------------
477 static int bcm63xx_cons_write_room (struct tty_struct *tty)
479 /* Pick a number. Any number. Polled I/O is used. */
484 * -------------------------------------------------------------------
485 * bcm_chars_in_buffer ()
487 * compute the amount of char left to be transmitted
488 * -------------------------------------------------------------------
490 static int bcm_chars_in_buffer (struct tty_struct *tty)
496 * -------------------------------------------------------------------
497 * bcm_flush_buffer ()
499 * Empty the output buffer
500 * -------------------------------------------------------------------
502 static void bcm_flush_buffer (struct tty_struct *tty)
508 * ------------------------------------------------------------
509 * bcm_throttle () and bcm_unthrottle ()
511 * This routine is called by the upper-layer tty layer to signal that
512 * incoming characters should be throttled (or not).
513 * ------------------------------------------------------------
515 static void bcm_throttle (struct tty_struct *tty)
517 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
519 info->x_char = STOP_CHAR(tty);
522 static void bcm_unthrottle (struct tty_struct *tty)
524 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
530 info->x_char = START_CHAR(tty);
534 static void bcm_send_xchar (struct tty_struct *tty, char ch)
536 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
539 bcm_start (info->tty);
543 * ------------------------------------------------------------
544 * rs_ioctl () and friends
545 * ------------------------------------------------------------
547 static int get_serial_info(struct bcm_serial *info, struct serial_struct *retinfo)
549 struct serial_struct tmp;
554 memset (&tmp, 0, sizeof(tmp));
555 tmp.type = info->type;
556 tmp.line = info->line;
557 tmp.port = (int) info->port;
560 tmp.baud_base = info->baud_base;
561 tmp.close_delay = info->close_delay;
562 tmp.closing_wait = info->closing_wait;
564 return copy_to_user (retinfo, &tmp, sizeof(*retinfo));
567 static int set_serial_info (struct bcm_serial *info, struct serial_struct *new_info)
569 struct serial_struct new_serial;
570 struct bcm_serial old_info;
576 copy_from_user (&new_serial, new_info, sizeof(new_serial));
579 if (!capable(CAP_SYS_ADMIN))
586 /* OK, past this point, all the error checking has been done.
587 * At this point, we start making changes.....
589 info->baud_base = new_serial.baud_base;
590 info->type = new_serial.type;
591 info->close_delay = new_serial.close_delay;
592 info->closing_wait = new_serial.closing_wait;
593 retval = startup (info);
598 * get_lsr_info - get line status register info
600 * Purpose: Let user call ioctl() to get info when the UART physically
601 * is emptied. On bus types like RS485, the transmitter must
602 * release the bus after transmitting. This must be done when
603 * the transmit shift register is empty, not be done when the
604 * transmit holding register is empty. This functionality
605 * allows an RS485 driver to be written in user space.
607 static int get_lsr_info (struct bcm_serial *info, unsigned int *value)
613 * This routine sends a break character out the serial port.
615 static void send_break (struct bcm_serial *info, int duration)
622 current->state = TASK_INTERRUPTIBLE;
624 /*save_flags (flags);
626 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
628 info->port->control |= XMITBREAK;
629 schedule_timeout(duration);
630 info->port->control &= ~XMITBREAK;
632 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
633 //restore_flags (flags);
636 static int bcm_ioctl (struct tty_struct * tty, struct file * file,
637 unsigned int cmd, unsigned long arg)
640 struct bcm_serial * info = (struct bcm_serial *)tty->driver_data;
643 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
644 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
645 (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT))
647 if (tty->flags & (1 << TTY_IO_ERROR))
653 case TCSBRK: /* SVID version: non-zero arg --> no break */
654 retval = tty_check_change (tty);
657 tty_wait_until_sent (tty, 0);
659 send_break (info, HZ/4); /* 1/4 second */
662 case TCSBRKP: /* support for POSIX tcsendbreak() */
663 retval = tty_check_change (tty);
666 tty_wait_until_sent (tty, 0);
667 send_break (info, arg ? arg*(HZ/10) : HZ/4);
671 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(long));
676 put_user (C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
681 error = get_user (arg, (unsigned long *)arg);
684 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
688 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(struct serial_struct));
692 return get_serial_info (info, (struct serial_struct *)arg);
695 return set_serial_info (info, (struct serial_struct *) arg);
697 case TIOCSERGETLSR: /* Get line status register */
698 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(unsigned int));
702 return get_lsr_info (info, (unsigned int *)arg);
705 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(struct bcm_serial));
710 copy_to_user((struct bcm_serial *)arg, info, sizeof(struct bcm_serial));
720 static void bcm_set_termios (struct tty_struct *tty, struct termios *old_termios)
722 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
724 if( tty->termios->c_cflag != old_termios->c_cflag )
725 change_speed (info->port, tty->termios->c_cflag);
729 * ------------------------------------------------------------
730 * bcm63xx_cons_close()
732 * This routine is called when the serial port gets closed. First, we
733 * wait for the last remaining data to be sent. Then, we turn off
734 * the transmit enable and receive enable flags.
735 * ------------------------------------------------------------
737 static void bcm63xx_cons_close (struct tty_struct *tty, struct file *filp)
739 struct bcm_serial * info = (struct bcm_serial *)tty->driver_data;
745 /*save_flags (flags);
747 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
749 if (tty_hung_up_p (filp))
751 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
752 //restore_flags (flags);
756 if ((tty->count == 1) && (info->count != 1))
759 /* Uh, oh. tty->count is 1, which means that the tty
760 * structure will be freed. Info->count should always
761 * be one in these conditions. If it's greater than
762 * one, we've got real problems, since it means the
763 * serial port won't be shutdown.
765 printk("bcm63xx_cons_close: bad serial port count; tty->count is 1, "
766 "info->count is %d\n", info->count);
770 if (--info->count < 0)
772 printk("ds_close: bad serial port count for ttys%d: %d\n",
773 info->line, info->count);
779 //restore_flags (flags);
780 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
784 /* Now we wait for the transmit buffer to clear; and we notify
785 * the line discipline to only process XON/XOFF characters.
789 /* At this point we stop accepting input. To do this, we
790 * disable the receive line status interrupts.
793 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
794 if (tty->driver->flush_buffer)
795 tty->driver->flush_buffer (tty);
797 if (tty->driver.flush_buffer)
798 tty->driver.flush_buffer (tty);
800 if (tty->ldisc.flush_buffer)
801 tty->ldisc.flush_buffer (tty);
806 if (tty->ldisc.num != tty_ldisc_get(N_TTY)->num)
808 if (tty->ldisc.close)
809 (tty->ldisc.close)(tty);
810 tty->ldisc = *tty_ldisc_get(N_TTY);
811 tty->termios->c_line = N_TTY;
813 (tty->ldisc.open)(tty);
815 if (info->blocked_open)
817 if (info->close_delay)
819 current->state = TASK_INTERRUPTIBLE;
820 schedule_timeout(info->close_delay);
822 wake_up_interruptible (&info->open_wait);
824 wake_up_interruptible (&info->close_wait);
826 //restore_flags (flags);
827 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
831 * bcm_hangup () --- called by tty_hangup() when a hangup is signaled.
833 static void bcm_hangup (struct tty_struct *tty)
836 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
842 wake_up_interruptible (&info->open_wait);
846 * ------------------------------------------------------------
847 * rs_open() and friends
848 * ------------------------------------------------------------
850 static int block_til_ready (struct tty_struct *tty, struct file *filp,
851 struct bcm_serial *info)
857 * This routine is called whenever a serial port is opened. It
858 * enables interrupts for a serial port. It also performs the
859 * serial-specific initialization for the tty structure.
861 static int bcm63xx_cons_open (struct tty_struct * tty, struct file * filp)
863 struct bcm_serial *info;
866 // Make sure we're only opening on of the ports we support
867 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
868 line = MINOR(tty->driver->cdev.dev) - tty->driver->minor_start;
870 line = MINOR(tty->device) - tty->driver.minor_start;
873 if ((line < 0) || (line >= BCM_NUM_UARTS))
879 info->port->intMask = 0; /* Clear any pending interrupts */
880 info->port->intMask = RXINT; /* Enable RX */
883 tty->driver_data = info;
885 BcmHalInterruptEnable (INTERRUPT_ID_UART);
887 // Start up serial port
888 retval = startup (info);
892 retval = block_til_ready (tty, filp, info);
897 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
898 info->pgrp = process_group(current);
899 info->session = current->signal->session;
901 info->session = current->session;
902 info->pgrp = current->pgrp;
909 static struct tty_operations rs_ops = {
910 .open = bcm63xx_cons_open,
911 .close = bcm63xx_cons_close,
912 .write = bcm63xx_cons_write,
913 .flush_chars = bcm63xx_cons_flush_chars,
914 .write_room = bcm63xx_cons_write_room,
915 .chars_in_buffer = bcm_chars_in_buffer,
916 .flush_buffer = bcm_flush_buffer,
918 .throttle = bcm_throttle,
919 .unthrottle = bcm_unthrottle,
920 .send_xchar = bcm_send_xchar,
921 .set_termios = bcm_set_termios,
924 .hangup = bcm_hangup,
927 /* --------------------------------------------------------------------------
928 Name: bcm63xx_serialinit
929 Purpose: Initialize our BCM63xx serial driver
930 -------------------------------------------------------------------------- */
931 static int __init bcm63xx_serialinit(void)
934 struct bcm_serial * info;
936 // Print the driver version information
938 serial_driver = alloc_tty_driver(BCM_NUM_UARTS);
942 serial_driver->owner = THIS_MODULE;
943 // serial_driver->devfs_name = "tts/";
944 // serial_driver.magic = TTY_DRIVER_MAGIC;
945 serial_driver->name = "ttyS";
946 serial_driver->major = TTY_MAJOR;
947 serial_driver->minor_start = 64;
948 // serial_driver.num = BCM_NUM_UARTS;
949 serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
950 serial_driver->subtype = SERIAL_TYPE_NORMAL;
951 serial_driver->init_termios = tty_std_termios;
952 serial_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
953 serial_driver->flags = TTY_DRIVER_REAL_RAW;
955 serial_driver->termios = serial_termios;
956 serial_driver->termios_locked = serial_termios_locked;
958 tty_set_operations(serial_driver, &rs_ops);
960 if (tty_register_driver (serial_driver))
961 panic("Couldn't register serial driver\n");
963 //save_flags(flags); cli();
964 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
966 for (i = 0; i < BCM_NUM_UARTS; i++)
970 info->magic = SERIAL_MAGIC;
971 info->port = (Uart *) ((char *)UART_BASE + (i * 0x20));
973 info->irq = (2 - i) + 8;
975 info->close_delay = 50;
976 info->closing_wait = 3000;
980 info->blocked_open = 0;
981 info->normal_termios = serial_driver->init_termios;
982 init_waitqueue_head(&info->open_wait);
983 init_waitqueue_head(&info->close_wait);
985 /* If we are pointing to address zero then punt - not correctly
986 * set up in setup.c to handle this.
990 BcmHalMapInterrupt(bcm_interrupt, 0, INTERRUPT_ID_UART);
993 /* order matters here... the trick is that flags
994 * is updated... in request_irq - to immediatedly obliterate
997 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
1001 module_init(bcm63xx_serialinit);
1003 /* --------------------------------------------------------------------------
1004 Name: bcm_console_print
1005 Purpose: bcm_console_print is registered for printk.
1006 The console_lock must be held when we get here.
1007 -------------------------------------------------------------------------- */
1008 static void bcm_console_print (struct console * cons, const char * str,
1013 for(i=0; i<count; i++, str++)
1023 static struct tty_driver * bcm_console_device(struct console * c, int *index)
1026 return serial_driver;
1029 static int __init bcm_console_setup(struct console * co, char * options)
1034 static struct console bcm_sercons = {
1036 .write = bcm_console_print,
1037 .device = bcm_console_device,
1038 .setup = bcm_console_setup,
1039 .flags = CON_PRINTBUFFER,
1043 static int __init bcm63xx_console_init(void)
1045 register_console(&bcm_sercons);
1049 console_initcall(bcm63xx_console_init);