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