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