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
);