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>
47 #include <6348_map_part.h>
48 #include <6348_intr.h>
50 static DEFINE_SPINLOCK(bcm963xx_serial_lock);
52 extern void _putc(char);
53 extern void _puts(const char *);
55 typedef struct bcm_serial {
62 unsigned short close_delay;
63 unsigned short closing_wait;
64 unsigned short line; /* port/line number */
65 unsigned short cflags; /* line configuration flag */
66 unsigned short x_char; /* xon/xoff character */
67 unsigned short read_status_mask; /* mask for read condition */
68 unsigned short ignore_status_mask; /* mask for ignore condition */
69 unsigned long event; /* mask used in BH */
70 int xmit_head; /* Position of the head */
71 int xmit_tail; /* Position of the tail */
72 int xmit_cnt; /* Count of the chars in the buffer */
73 int count; /* indicates how many times it has been opened */
76 struct async_icount icount; /* keep track of things ... */
77 struct tty_struct *tty; /* tty associated */
78 struct termios normal_termios;
80 wait_queue_head_t open_wait;
81 wait_queue_head_t close_wait;
83 long session; /* Session of opening process */
84 long pgrp; /* pgrp of opening process */
86 unsigned char is_initialized;
90 /*---------------------------------------------------------------------*/
91 /* Define bits in the Interrupt Enable register */
92 /*---------------------------------------------------------------------*/
93 /* Enable receive interrupt */
94 #define RXINT (RXFIFONE|RXOVFERR)
96 /* Enable transmit interrupt */
97 #define TXINT (TXFIFOEMT|TXUNDERR|TXOVFERR)
99 /* Enable receiver line status interrupt */
100 #define LSINT (RXBRK|RXPARERR|RXFRAMERR)
102 #define BCM_NUM_UARTS 1
104 #define BD_BCM63XX_TIMER_CLOCK_INPUT (FPERIPH)
107 static struct bcm_serial multi[BCM_NUM_UARTS];
108 static struct bcm_serial *lines[BCM_NUM_UARTS];
109 static struct tty_driver *serial_driver;
110 static struct termios *serial_termios[BCM_NUM_UARTS];
111 static struct termios *serial_termios_locked[BCM_NUM_UARTS];
114 static void bcm_stop (struct tty_struct *tty);
115 static void bcm_start (struct tty_struct *tty);
116 static inline void receive_chars (struct bcm_serial * info);
117 static int startup (struct bcm_serial *info);
118 static void shutdown (struct bcm_serial * info);
119 static void change_speed( volatile Uart *pUart, tcflag_t cFlag );
120 static void bcm63xx_cons_flush_chars (struct tty_struct *tty);
121 static int bcm63xx_cons_write (struct tty_struct *tty,
122 const unsigned char *buf, int count);
123 static int bcm63xx_cons_write_room (struct tty_struct *tty);
124 static int bcm_chars_in_buffer (struct tty_struct *tty);
125 static void bcm_flush_buffer (struct tty_struct *tty);
126 static void bcm_throttle (struct tty_struct *tty);
127 static void bcm_unthrottle (struct tty_struct *tty);
128 static void bcm_send_xchar (struct tty_struct *tty, char ch);
129 static int get_serial_info(struct bcm_serial *info, struct serial_struct *retinfo);
130 static int set_serial_info (struct bcm_serial *info, struct serial_struct *new_info);
131 static int get_lsr_info (struct bcm_serial *info, unsigned int *value);
132 static void send_break (struct bcm_serial *info, int duration);
133 static int bcm_ioctl (struct tty_struct * tty, struct file * file,
134 unsigned int cmd, unsigned long arg);
135 static void bcm_set_termios (struct tty_struct *tty, struct termios *old_termios);
136 static void bcm63xx_cons_close (struct tty_struct *tty, struct file *filp);
137 static void bcm_hangup (struct tty_struct *tty);
138 static int block_til_ready (struct tty_struct *tty, struct file *filp, struct bcm_serial *info);
139 static int bcm63xx_cons_open (struct tty_struct * tty, struct file * filp);
140 static int __init bcm63xx_serialinit(void);
144 * ------------------------------------------------------------
145 * rs_stop () and rs_start ()
147 * These routines are called before setting or resetting
148 * tty->stopped. They enable or disable transmitter interrupts,
150 * ------------------------------------------------------------
152 static void bcm_stop (struct tty_struct *tty)
156 static void bcm_start (struct tty_struct *tty)
158 _puts(CARDNAME " Start\n");
162 * ------------------------------------------------------------
165 * This routine deals with inputs from any lines.
166 * ------------------------------------------------------------
168 static inline void receive_chars (struct bcm_serial * info)
170 struct tty_struct *tty = 0;
171 struct async_icount * icount;
173 unsigned short status, tmp;
175 while ((status = info->port->intStatus) & RXINT)
177 char flag_char = TTY_NORMAL;
179 if (status & RXFIFONE)
180 ch = info->port->Data; // Read the character
181 tty = info->tty; /* now tty points to the proper dev */
182 icount = &info->icount;
185 if (!tty_buffer_request_room(tty, 1))
190 flag_char = TTY_BREAK;
193 // keep track of the statistics
194 if (status & (RXFRAMERR | RXPARERR | RXOVFERR))
196 if (status & RXPARERR) /* parity error */
199 if (status & RXFRAMERR) /* frame error */
201 if (status & RXOVFERR)
203 // Overflow. Reset the RX FIFO
204 info->port->fifoctl |= RSTRXFIFOS;
207 // check to see if we should ignore the character
208 // and mask off conditions that should be ignored
209 if (status & info->ignore_status_mask)
215 // Mask off the error conditions we want to ignore
216 tmp = status & info->read_status_mask;
219 flag_char = TTY_PARITY;
224 flag_char = TTY_FRAME;
228 tty_insert_flip_char(tty, ch, flag_char);
230 flag_char = TTY_OVERRUN;
231 if (!tty_buffer_request_room(tty, 1))
235 tty_insert_flip_char(tty, ch, flag_char);
238 tty_flip_buffer_push(tty);
239 tty_schedule_flip(tty);
245 * ------------------------------------------------------------
248 * this is the main interrupt routine for the chip.
249 * It deals with the multiple ports.
250 * ------------------------------------------------------------
252 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
253 static irqreturn_t bcm_interrupt (int irq, void * dev)
255 static void bcm_interrupt (int irq, void * dev, struct pt_regs * regs)
258 struct bcm_serial * info = lines[0];
261 /* get pending interrupt flags from UART */
263 /* Mask with only the serial interrupts that are enabled */
264 intStat = info->port->intStatus & info->port->intMask;
268 receive_chars (info);
271 info->port->intStatus = TXINT;
272 else /* don't know what it was, so let's mask it */
273 info->port->intMask &= ~intStat;
275 intStat = info->port->intStatus & info->port->intMask;
278 // Clear the interrupt
279 BcmHalInterruptEnable (INTERRUPT_ID_UART);
280 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
286 * -------------------------------------------------------------------
289 * various initialization tasks
290 * -------------------------------------------------------------------
292 static int startup (struct bcm_serial *info)
294 // Port is already started...
299 * -------------------------------------------------------------------
302 * This routine will shutdown a serial port; interrupts are disabled, and
303 * DTR is dropped if the hangup on close termio flag is on.
304 * -------------------------------------------------------------------
306 static void shutdown (struct bcm_serial * info)
309 if (!info->is_initialized)
312 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
314 info->port->control &= ~(BRGEN|TXEN|RXEN);
316 set_bit (TTY_IO_ERROR, &info->tty->flags);
317 info->is_initialized = 0;
319 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
322 * -------------------------------------------------------------------
325 * Set the baud rate, character size, parity and stop bits.
326 * -------------------------------------------------------------------
328 static void change_speed( volatile Uart *pUart, tcflag_t cFlag )
330 unsigned long ulFlags, ulBaud, ulClockFreqHz, ulTmp;
332 spin_lock_irqsave(&bcm963xx_serial_lock, ulFlags);
333 switch( cFlag & (CBAUD | CBAUDEX) )
391 /* Calculate buad rate. */
392 ulClockFreqHz = BD_BCM63XX_TIMER_CLOCK_INPUT;
393 ulTmp = (ulClockFreqHz / ulBaud) / 16;
395 ulTmp /= 2; /* Rounding up, so sub is already accounted for */
397 ulTmp = (ulTmp / 2) - 1; /* Rounding down so we must sub 1 */
398 pUart->baudword = ulTmp;
400 /* Set character size, stop bits and parity. */
401 switch( cFlag & CSIZE )
404 ulTmp = BITS5SYM; /* select transmit 5 bit data size */
407 ulTmp = BITS6SYM; /* select transmit 6 bit data size */
410 ulTmp = BITS7SYM; /* select transmit 7 bit data size */
413 ulTmp = BITS8SYM; /* select transmit 8 bit data size */
417 ulTmp |= TWOSTOP; /* select 2 stop bits */
419 ulTmp |= ONESTOP; /* select one stop bit */
421 /* Write these values into the config reg. */
422 pUart->config = ulTmp;
423 pUart->control &= ~(RXPARITYEN | TXPARITYEN | RXPARITYEVEN | TXPARITYEVEN);
424 switch( cFlag & (PARENB | PARODD) )
427 pUart->control |= RXPARITYEN | TXPARITYEN;
430 pUart->control |= RXPARITYEN | TXPARITYEN | RXPARITYEVEN | TXPARITYEVEN;
437 /* Reset and flush uart */
438 pUart->fifoctl = RSTTXFIFOS | RSTRXFIFOS;
439 spin_unlock_irqrestore(&bcm963xx_serial_lock, ulFlags);
444 * -------------------------------------------------------------------
447 * Nothing to flush. Polled I/O is used.
448 * -------------------------------------------------------------------
450 static void bcm63xx_cons_flush_chars (struct tty_struct *tty)
456 * -------------------------------------------------------------------
457 * bcm63xx_cons_write ()
459 * Main output routine using polled I/O.
460 * -------------------------------------------------------------------
462 static int bcm63xx_cons_write (struct tty_struct *tty,
463 const unsigned char *buf, int count)
467 for (c = 0; c < count; c++)
473 * -------------------------------------------------------------------
474 * bcm63xx_cons_write_room ()
476 * Compute the amount of space available for writing.
477 * -------------------------------------------------------------------
479 static int bcm63xx_cons_write_room (struct tty_struct *tty)
481 /* Pick a number. Any number. Polled I/O is used. */
486 * -------------------------------------------------------------------
487 * bcm_chars_in_buffer ()
489 * compute the amount of char left to be transmitted
490 * -------------------------------------------------------------------
492 static int bcm_chars_in_buffer (struct tty_struct *tty)
498 * -------------------------------------------------------------------
499 * bcm_flush_buffer ()
501 * Empty the output buffer
502 * -------------------------------------------------------------------
504 static void bcm_flush_buffer (struct tty_struct *tty)
510 * ------------------------------------------------------------
511 * bcm_throttle () and bcm_unthrottle ()
513 * This routine is called by the upper-layer tty layer to signal that
514 * incoming characters should be throttled (or not).
515 * ------------------------------------------------------------
517 static void bcm_throttle (struct tty_struct *tty)
519 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
521 info->x_char = STOP_CHAR(tty);
524 static void bcm_unthrottle (struct tty_struct *tty)
526 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
532 info->x_char = START_CHAR(tty);
536 static void bcm_send_xchar (struct tty_struct *tty, char ch)
538 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
541 bcm_start (info->tty);
545 * ------------------------------------------------------------
546 * rs_ioctl () and friends
547 * ------------------------------------------------------------
549 static int get_serial_info(struct bcm_serial *info, struct serial_struct *retinfo)
551 struct serial_struct tmp;
556 memset (&tmp, 0, sizeof(tmp));
557 tmp.type = info->type;
558 tmp.line = info->line;
559 tmp.port = (int) info->port;
562 tmp.baud_base = info->baud_base;
563 tmp.close_delay = info->close_delay;
564 tmp.closing_wait = info->closing_wait;
566 return copy_to_user (retinfo, &tmp, sizeof(*retinfo));
569 static int set_serial_info (struct bcm_serial *info, struct serial_struct *new_info)
571 struct serial_struct new_serial;
572 struct bcm_serial old_info;
578 copy_from_user (&new_serial, new_info, sizeof(new_serial));
581 if (!capable(CAP_SYS_ADMIN))
588 /* OK, past this point, all the error checking has been done.
589 * At this point, we start making changes.....
591 info->baud_base = new_serial.baud_base;
592 info->type = new_serial.type;
593 info->close_delay = new_serial.close_delay;
594 info->closing_wait = new_serial.closing_wait;
595 retval = startup (info);
600 * get_lsr_info - get line status register info
602 * Purpose: Let user call ioctl() to get info when the UART physically
603 * is emptied. On bus types like RS485, the transmitter must
604 * release the bus after transmitting. This must be done when
605 * the transmit shift register is empty, not be done when the
606 * transmit holding register is empty. This functionality
607 * allows an RS485 driver to be written in user space.
609 static int get_lsr_info (struct bcm_serial *info, unsigned int *value)
615 * This routine sends a break character out the serial port.
617 static void send_break (struct bcm_serial *info, int duration)
624 current->state = TASK_INTERRUPTIBLE;
626 /*save_flags (flags);
628 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
630 info->port->control |= XMITBREAK;
631 schedule_timeout(duration);
632 info->port->control &= ~XMITBREAK;
634 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
635 //restore_flags (flags);
638 static int bcm_ioctl (struct tty_struct * tty, struct file * file,
639 unsigned int cmd, unsigned long arg)
642 struct bcm_serial * info = (struct bcm_serial *)tty->driver_data;
645 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
646 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
647 (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT))
649 if (tty->flags & (1 << TTY_IO_ERROR))
655 case TCSBRK: /* SVID version: non-zero arg --> no break */
656 retval = tty_check_change (tty);
659 tty_wait_until_sent (tty, 0);
661 send_break (info, HZ/4); /* 1/4 second */
664 case TCSBRKP: /* support for POSIX tcsendbreak() */
665 retval = tty_check_change (tty);
668 tty_wait_until_sent (tty, 0);
669 send_break (info, arg ? arg*(HZ/10) : HZ/4);
673 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(long));
678 put_user (C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
683 error = get_user (arg, (unsigned long *)arg);
686 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
690 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(struct serial_struct));
694 return get_serial_info (info, (struct serial_struct *)arg);
697 return set_serial_info (info, (struct serial_struct *) arg);
699 case TIOCSERGETLSR: /* Get line status register */
700 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(unsigned int));
704 return get_lsr_info (info, (unsigned int *)arg);
707 error = access_ok (VERIFY_WRITE, (void *)arg, sizeof(struct bcm_serial));
712 copy_to_user((struct bcm_serial *)arg, info, sizeof(struct bcm_serial));
722 static void bcm_set_termios (struct tty_struct *tty, struct termios *old_termios)
724 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
726 if( tty->termios->c_cflag != old_termios->c_cflag )
727 change_speed (info->port, tty->termios->c_cflag);
731 * ------------------------------------------------------------
732 * bcm63xx_cons_close()
734 * This routine is called when the serial port gets closed. First, we
735 * wait for the last remaining data to be sent. Then, we turn off
736 * the transmit enable and receive enable flags.
737 * ------------------------------------------------------------
739 static void bcm63xx_cons_close (struct tty_struct *tty, struct file *filp)
741 struct bcm_serial * info = (struct bcm_serial *)tty->driver_data;
747 /*save_flags (flags);
749 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
751 if (tty_hung_up_p (filp))
753 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
754 //restore_flags (flags);
758 if ((tty->count == 1) && (info->count != 1))
761 /* Uh, oh. tty->count is 1, which means that the tty
762 * structure will be freed. Info->count should always
763 * be one in these conditions. If it's greater than
764 * one, we've got real problems, since it means the
765 * serial port won't be shutdown.
767 printk("bcm63xx_cons_close: bad serial port count; tty->count is 1, "
768 "info->count is %d\n", info->count);
772 if (--info->count < 0)
774 printk("ds_close: bad serial port count for ttys%d: %d\n",
775 info->line, info->count);
781 //restore_flags (flags);
782 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
786 /* Now we wait for the transmit buffer to clear; and we notify
787 * the line discipline to only process XON/XOFF characters.
791 /* At this point we stop accepting input. To do this, we
792 * disable the receive line status interrupts.
795 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
796 if (tty->driver->flush_buffer)
797 tty->driver->flush_buffer (tty);
799 if (tty->driver.flush_buffer)
800 tty->driver.flush_buffer (tty);
802 if (tty->ldisc.flush_buffer)
803 tty->ldisc.flush_buffer (tty);
808 if (tty->ldisc.num != tty_ldisc_get(N_TTY)->num)
810 if (tty->ldisc.close)
811 (tty->ldisc.close)(tty);
812 tty->ldisc = *tty_ldisc_get(N_TTY);
813 tty->termios->c_line = N_TTY;
815 (tty->ldisc.open)(tty);
817 if (info->blocked_open)
819 if (info->close_delay)
821 current->state = TASK_INTERRUPTIBLE;
822 schedule_timeout(info->close_delay);
824 wake_up_interruptible (&info->open_wait);
826 wake_up_interruptible (&info->close_wait);
828 //restore_flags (flags);
829 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
833 * bcm_hangup () --- called by tty_hangup() when a hangup is signaled.
835 static void bcm_hangup (struct tty_struct *tty)
838 struct bcm_serial *info = (struct bcm_serial *)tty->driver_data;
844 wake_up_interruptible (&info->open_wait);
848 * ------------------------------------------------------------
849 * rs_open() and friends
850 * ------------------------------------------------------------
852 static int block_til_ready (struct tty_struct *tty, struct file *filp,
853 struct bcm_serial *info)
859 * This routine is called whenever a serial port is opened. It
860 * enables interrupts for a serial port. It also performs the
861 * serial-specific initialization for the tty structure.
863 static int bcm63xx_cons_open (struct tty_struct * tty, struct file * filp)
865 struct bcm_serial *info;
868 // Make sure we're only opening on of the ports we support
869 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
870 line = MINOR(tty->driver->cdev.dev) - tty->driver->minor_start;
872 line = MINOR(tty->device) - tty->driver.minor_start;
875 if ((line < 0) || (line >= BCM_NUM_UARTS))
881 info->port->intMask = 0; /* Clear any pending interrupts */
882 info->port->intMask = RXINT; /* Enable RX */
885 tty->driver_data = info;
887 BcmHalInterruptEnable (INTERRUPT_ID_UART);
889 // Start up serial port
890 retval = startup (info);
894 retval = block_til_ready (tty, filp, info);
899 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
900 info->pgrp = process_group(current);
901 info->session = current->signal->session;
903 info->session = current->session;
904 info->pgrp = current->pgrp;
911 static struct tty_operations rs_ops = {
912 .open = bcm63xx_cons_open,
913 .close = bcm63xx_cons_close,
914 .write = bcm63xx_cons_write,
915 .flush_chars = bcm63xx_cons_flush_chars,
916 .write_room = bcm63xx_cons_write_room,
917 .chars_in_buffer = bcm_chars_in_buffer,
918 .flush_buffer = bcm_flush_buffer,
920 .throttle = bcm_throttle,
921 .unthrottle = bcm_unthrottle,
922 .send_xchar = bcm_send_xchar,
923 .set_termios = bcm_set_termios,
926 .hangup = bcm_hangup,
929 /* --------------------------------------------------------------------------
930 Name: bcm63xx_serialinit
931 Purpose: Initialize our BCM63xx serial driver
932 -------------------------------------------------------------------------- */
933 static int __init bcm63xx_serialinit(void)
936 struct bcm_serial * info;
938 // Print the driver version information
940 serial_driver = alloc_tty_driver(BCM_NUM_UARTS);
944 serial_driver->owner = THIS_MODULE;
945 // serial_driver->devfs_name = "tts/";
946 // serial_driver.magic = TTY_DRIVER_MAGIC;
947 serial_driver->name = "ttyS";
948 serial_driver->major = TTY_MAJOR;
949 serial_driver->minor_start = 64;
950 // serial_driver.num = BCM_NUM_UARTS;
951 serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
952 serial_driver->subtype = SERIAL_TYPE_NORMAL;
953 serial_driver->init_termios = tty_std_termios;
954 serial_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
955 serial_driver->flags = TTY_DRIVER_REAL_RAW;
957 serial_driver->termios = serial_termios;
958 serial_driver->termios_locked = serial_termios_locked;
960 tty_set_operations(serial_driver, &rs_ops);
962 if (tty_register_driver (serial_driver))
963 panic("Couldn't register serial driver\n");
965 //save_flags(flags); cli();
966 spin_lock_irqsave(&bcm963xx_serial_lock, flags);
968 for (i = 0; i < BCM_NUM_UARTS; i++)
972 info->magic = SERIAL_MAGIC;
973 info->port = (Uart *) ((char *)UART_BASE + (i * 0x20));
975 info->irq = (2 - i) + 8;
977 info->close_delay = 50;
978 info->closing_wait = 3000;
982 info->blocked_open = 0;
983 info->normal_termios = serial_driver->init_termios;
984 init_waitqueue_head(&info->open_wait);
985 init_waitqueue_head(&info->close_wait);
987 /* If we are pointing to address zero then punt - not correctly
988 * set up in setup.c to handle this.
992 BcmHalMapInterrupt(bcm_interrupt, 0, INTERRUPT_ID_UART);
995 /* order matters here... the trick is that flags
996 * is updated... in request_irq - to immediatedly obliterate
999 spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
1003 module_init(bcm63xx_serialinit);
1005 /* --------------------------------------------------------------------------
1006 Name: bcm_console_print
1007 Purpose: bcm_console_print is registered for printk.
1008 The console_lock must be held when we get here.
1009 -------------------------------------------------------------------------- */
1010 static void bcm_console_print (struct console * cons, const char * str,
1015 for(i=0; i<count; i++, str++)
1025 static struct tty_driver * bcm_console_device(struct console * c, int *index)
1028 return serial_driver;
1031 static int __init bcm_console_setup(struct console * co, char * options)
1036 static struct console bcm_sercons = {
1038 .write = bcm_console_print,
1039 .device = bcm_console_device,
1040 .setup = bcm_console_setup,
1041 .flags = CON_PRINTBUFFER,
1045 static int __init bcm63xx_console_init(void)
1047 register_console(&bcm_sercons);
1051 console_initcall(bcm63xx_console_init);