1 /*
2 * linux/drivers/char/serial_amba.c
3 *
4 * Driver for AMBA serial ports
5 *
6 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
7 *
8 * Copyright 1999 ARM Limited
9 * Copyright (C) 2000 Deep Blue Solutions Ltd.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 *
26 * This is a generic driver for ARM AMBA-type serial ports. They
27 * have a lot of 16550-like features, but are not register compatable.
28 * Note that although they do have CTS, DCD and DSR inputs, they do
29 * not have an RI input, nor do they have DTR or RTS outputs. If
30 * required, these have to be supplied via some other means (eg, GPIO)
31 * and hooked into this driver.
32 *
33 * This could very easily become a generic serial driver for dumb UARTs
34 * (eg, {82,16x}50, 21285, SA1100).
35 */
36
37 #include <linux/config.h>
38 #include <linux/module.h>
39 #include <linux/errno.h>
40 #include <linux/signal.h>
41 #include <linux/sched.h>
42 #include <linux/interrupt.h>
43 #include <linux/tty.h>
44 #include <linux/tty_flip.h>
45 #include <linux/major.h>
46 #include <linux/string.h>
47 #include <linux/fcntl.h>
48 #include <linux/ptrace.h>
49 #include <linux/ioport.h>
50 #include <linux/mm.h>
51 #include <linux/malloc.h>
52 #include <linux/init.h>
53 #include <linux/circ_buf.h>
54 #include <linux/serial.h>
55 #include <linux/console.h>
56 #include <linux/sysrq.h>
57
58 #include <asm/system.h>
59 #include <asm/io.h>
60 #include <asm/irq.h>
61 #include <asm/uaccess.h>
62 #include <asm/bitops.h>
63
64 #include <asm/hardware/serial_amba.h>
65
66 #define SERIAL_AMBA_NAME "ttyAM"
67 #define SERIAL_AMBA_MAJOR 204
68 #define SERIAL_AMBA_MINOR 16
69 #define SERIAL_AMBA_NR 2
70
71 #define CALLOUT_AMBA_NAME "cuaam"
72 #define CALLOUT_AMBA_MAJOR 205
73 #define CALLOUT_AMBA_MINOR 16
74 #define CALLOUT_AMBA_NR SERIAL_AMBA_NR
75
76 #ifndef TRUE
77 #define TRUE 1
78 #endif
79 #ifndef FALSE
80 #define FALSE 0
81 #endif
82
83 #define DEBUG 0
84 #define DEBUG_LEDS 0
85
86 #if DEBUG_LEDS
87 extern int get_leds(void);
88 extern int set_leds(int);
89 #endif
90
91 /*
92 * Access routines for the AMBA UARTs
93 */
94 #define UART_GET_INT_STATUS(p) IO_READ((p)->uart_base + AMBA_UARTIIR)
95 #define UART_GET_FR(p) IO_READ((p)->uart_base + AMBA_UARTFR)
96 #define UART_GET_CHAR(p) IO_READ((p)->uart_base + AMBA_UARTDR)
97 #define UART_PUT_CHAR(p, c) IO_WRITE((p)->uart_base + AMBA_UARTDR, (c))
98 #define UART_GET_RSR(p) IO_READ((p)->uart_base + AMBA_UARTRSR)
99 #define UART_GET_CR(p) IO_READ((p)->uart_base + AMBA_UARTCR)
100 #define UART_PUT_CR(p,c) IO_WRITE((p)->uart_base + AMBA_UARTCR, (c))
101 #define UART_GET_LCRL(p) IO_READ((p)->uart_base + AMBA_UARTLCR_L)
102 #define UART_PUT_LCRL(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_L, (c))
103 #define UART_GET_LCRM(p) IO_READ((p)->uart_base + AMBA_UARTLCR_M)
104 #define UART_PUT_LCRM(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_M, (c))
105 #define UART_GET_LCRH(p) IO_READ((p)->uart_base + AMBA_UARTLCR_H)
106 #define UART_PUT_LCRH(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_H, (c))
107 #define UART_RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0)
108 #define UART_TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0)
109 #define UART_TX_EMPTY(p) ((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
110
111 #define AMBA_UARTRSR_ANY (AMBA_UARTRSR_OE|AMBA_UARTRSR_BE|AMBA_UARTRSR_PE|AMBA_UARTRSR_FE)
112 #define AMBA_UARTFR_MODEM_ANY (AMBA_UARTFR_DCD|AMBA_UARTFR_DSR|AMBA_UARTFR_CTS)
113
114 /*
115 * Things needed by tty driver
116 */
117 static struct tty_driver ambanormal_driver, ambacallout_driver;
118 static int ambauart_refcount;
119 static struct tty_struct *ambauart_table[SERIAL_AMBA_NR];
120 static struct termios *ambauart_termios[SERIAL_AMBA_NR];
121 static struct termios *ambauart_termios_locked[SERIAL_AMBA_NR];
122
123 #if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
124 #define SUPPORT_SYSRQ
125 #endif
126
127 /*
128 * Things needed internally to this driver
129 */
130
131 /*
132 * tmp_buf is used as a temporary buffer by serial_write. We need to
133 * lock it in case the copy_from_user blocks while swapping in a page,
134 * and some other program tries to do a serial write at the same time.
135 * Since the lock will only come under contention when the system is
136 * swapping and available memory is low, it makes sense to share one
137 * buffer across all the serial ports, since it significantly saves
138 * memory if large numbers of serial ports are open.
139 */
140 static u_char *tmp_buf;
141 static DECLARE_MUTEX(tmp_buf_sem);
142
143 #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
144
145 /* number of characters left in xmit buffer before we ask for more */
146 #define WAKEUP_CHARS 256
147 #define AMBA_ISR_PASS_LIMIT 256
148
149 #define EVT_WRITE_WAKEUP 0
150
151 struct amba_icount {
152 __u32 cts;
153 __u32 dsr;
154 __u32 rng;
155 __u32 dcd;
156 __u32 rx;
157 __u32 tx;
158 __u32 frame;
159 __u32 overrun;
160 __u32 parity;
161 __u32 brk;
162 __u32 buf_overrun;
163 };
164
165 /*
166 * Static information about the port
167 */
168 struct amba_port {
169 unsigned int uart_base;
170 unsigned int irq;
171 unsigned int uartclk;
172 unsigned int fifosize;
173 unsigned int tiocm_support;
174 void (*set_mctrl)(struct amba_port *, u_int mctrl);
175 };
176
177 /*
178 * This is the state information which is persistent across opens
179 */
180 struct amba_state {
181 struct amba_icount icount;
182 unsigned int line;
183 unsigned int close_delay;
184 unsigned int closing_wait;
185 unsigned int custom_divisor;
186 unsigned int flags;
187 struct termios normal_termios;
188 struct termios callout_termios;
189
190 int count;
191 struct amba_info *info;
192 };
193
194 #define AMBA_XMIT_SIZE 1024
195 /*
196 * This is the state information which is only valid when the port is open.
197 */
198 struct amba_info {
199 struct amba_port *port;
200 struct amba_state *state;
201 struct tty_struct *tty;
202 unsigned char x_char;
203 unsigned char old_status;
204 unsigned char read_status_mask;
205 unsigned char ignore_status_mask;
206 struct circ_buf xmit;
207 unsigned int flags;
208 #ifdef SUPPORT_SYSRQ
209 unsigned long sysrq;
210 #endif
211
212 unsigned int event;
213 unsigned int timeout;
214 unsigned int lcr_h;
215 unsigned int mctrl;
216 int blocked_open;
217 pid_t session;
218 pid_t pgrp;
219
220 struct tasklet_struct tlet;
221
222 wait_queue_head_t open_wait;
223 wait_queue_head_t close_wait;
224 wait_queue_head_t delta_msr_wait;
225 };
226
227 #ifdef CONFIG_SERIAL_AMBA_CONSOLE
228 static struct console ambauart_cons;
229 #endif
230 static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios);
231 static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout);
232
233 #if 1 //def CONFIG_SERIAL_INTEGRATOR
234 static void amba_set_mctrl_null(struct amba_port *port, u_int mctrl)
235 {
236 }
237
238 static struct amba_port amba_ports[SERIAL_AMBA_NR] = {
239 {
240 uart_base: IO_ADDRESS(INTEGRATOR_UART0_BASE),
241 irq: IRQ_UARTINT0,
242 uartclk: 14745600,
243 fifosize: 8,
244 set_mctrl: amba_set_mctrl_null,
245 },
246 {
247 uart_base: IO_ADDRESS(INTEGRATOR_UART1_BASE),
248 irq: IRQ_UARTINT1,
249 uartclk: 14745600,
250 fifosize: 8,
251 set_mctrl: amba_set_mctrl_null,
252 }
253 };
254 #endif
255
256 static struct amba_state amba_state[SERIAL_AMBA_NR];
257
258 static void ambauart_enable_rx_interrupt(struct amba_info *info)
259 {
260 unsigned int cr;
261
262 cr = UART_GET_CR(info->port);
263 cr |= AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE;
264 UART_PUT_CR(info->port, cr);
265 }
266
267 static void ambauart_disable_rx_interrupt(struct amba_info *info)
268 {
269 unsigned int cr;
270
271 cr = UART_GET_CR(info->port);
272 cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE);
273 UART_PUT_CR(info->port, cr);
274 }
275
276 static void ambauart_enable_tx_interrupt(struct amba_info *info)
277 {
278 unsigned int cr;
279
280 cr = UART_GET_CR(info->port);
281 cr |= AMBA_UARTCR_TIE;
282 UART_PUT_CR(info->port, cr);
283 }
284
285 static void ambauart_disable_tx_interrupt(struct amba_info *info)
286 {
287 unsigned int cr;
288
289 cr = UART_GET_CR(info->port);
290 cr &= ~AMBA_UARTCR_TIE;
291 UART_PUT_CR(info->port, cr);
292 }
293
294 static void ambauart_stop(struct tty_struct *tty)
295 {
296 struct amba_info *info = tty->driver_data;
297 unsigned long flags;
298
299 save_flags(flags); cli();
300 ambauart_disable_tx_interrupt(info);
301 restore_flags(flags);
302 }
303
304 static void ambauart_start(struct tty_struct *tty)
305 {
306 struct amba_info *info = tty->driver_data;
307 unsigned long flags;
308
309 save_flags(flags); cli();
310 if (info->xmit.head != info->xmit.tail
311 && info->xmit.buf)
312 ambauart_enable_tx_interrupt(info);
313 restore_flags(flags);
314 }
315
316
317 /*
318 * This routine is used by the interrupt handler to schedule
319 * processing in the software interrupt portion of the driver.
320 */
321 static void ambauart_event(struct amba_info *info, int event)
322 {
323 info->event |= 1 << event;
324 tasklet_schedule(&info->tlet);
325 }
326
327 static void
328 #ifdef SUPPORT_SYSRQ
329 ambauart_rx_chars(struct amba_info *info, struct pt_regs *regs)
330 #else
331 ambauart_rx_chars(struct amba_info *info)
332 #endif
333 {
334 struct tty_struct *tty = info->tty;
335 unsigned int status, ch, rsr, flg, ignored = 0;
336 struct amba_icount *icount = &info->state->icount;
337 struct amba_port *port = info->port;
338
339 status = UART_GET_FR(port);
340 while (UART_RX_DATA(status)) {
341 ch = UART_GET_CHAR(port);
342
343 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
344 goto ignore_char;
345 icount->rx++;
346
347 flg = TTY_NORMAL;
348
349 /*
350 * Note that the error handling code is
351 * out of the main execution path
352 */
353 rsr = UART_GET_RSR(port);
354 if (rsr & AMBA_UARTRSR_ANY)
355 goto handle_error;
356 #ifdef SUPPORT_SYSRQ
357 if (info->sysrq) {
358 if (ch && time_before(jiffies, info->sysrq)) {
359 handle_sysrq(ch, regs, NULL, NULL);
360 info->sysrq = 0;
361 goto ignore_char;
362 }
363 info->sysrq = 0;
364 }
365 #endif
366 error_return:
367 *tty->flip.flag_buf_ptr++ = flg;
368 *tty->flip.char_buf_ptr++ = ch;
369 tty->flip.count++;
370 ignore_char:
371 status = UART_GET_FR(port);
372 }
373 out:
374 tty_flip_buffer_push(tty);
375 return;
376
377 handle_error:
378 if (rsr & AMBA_UARTRSR_BE) {
379 rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
380 icount->brk++;
381
382 #ifdef SUPPORT_SYSRQ
383 if (info->state->line == ambauart_cons.index) {
384 if (!info->sysrq) {
385 info->sysrq = jiffies + HZ*5;
386 goto ignore_char;
387 }
388 }
389 #endif
390 } else if (rsr & AMBA_UARTRSR_PE)
391 icount->parity++;
392 else if (rsr & AMBA_UARTRSR_FE)
393 icount->frame++;
394 if (rsr & AMBA_UARTRSR_OE)
395 icount->overrun++;
396
397 if (rsr & info->ignore_status_mask) {
398 if (++ignored > 100)
399 goto out;
400 goto ignore_char;
401 }
402 rsr &= info->read_status_mask;
403
404 if (rsr & AMBA_UARTRSR_BE)
405 flg = TTY_BREAK;
406 else if (rsr & AMBA_UARTRSR_PE)
407 flg = TTY_PARITY;
408 else if (rsr & AMBA_UARTRSR_FE)
409 flg = TTY_FRAME;
410
411 if (rsr & AMBA_UARTRSR_OE) {
412 /*
413 * CHECK: does overrun affect the current character?
414 * ASSUMPTION: it does not.
415 */
416 *tty->flip.flag_buf_ptr++ = flg;
417 *tty->flip.char_buf_ptr++ = ch;
418 tty->flip.count++;
419 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
420 goto ignore_char;
421 ch = 0;
422 flg = TTY_OVERRUN;
423 }
424 #ifdef SUPPORT_SYSRQ
425 info->sysrq = 0;
426 #endif
427 goto error_return;
428 }
429
430 static void ambauart_tx_chars(struct amba_info *info)
431 {
432 struct amba_port *port = info->port;
433 int count;
434
435 if (info->x_char) {
436 UART_PUT_CHAR(port, info->x_char);
437 info->state->icount.tx++;
438 info->x_char = 0;
439 return;
440 }
441 if (info->xmit.head == info->xmit.tail
442 || info->tty->stopped
443 || info->tty->hw_stopped) {
444 ambauart_disable_tx_interrupt(info);
445 return;
446 }
447
448 count = port->fifosize;
449 do {
450 UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
451 info->xmit.tail = (info->xmit.tail + 1) & (AMBA_XMIT_SIZE - 1);
452 info->state->icount.tx++;
453 if (info->xmit.head == info->xmit.tail)
454 break;
455 } while (--count > 0);
456
457 if (CIRC_CNT(info->xmit.head,
458 info->xmit.tail,
459 AMBA_XMIT_SIZE) < WAKEUP_CHARS)
460 ambauart_event(info, EVT_WRITE_WAKEUP);
461
462 if (info->xmit.head == info->xmit.tail) {
463 ambauart_disable_tx_interrupt(info);
464 }
465 }
466
467 static void ambauart_modem_status(struct amba_info *info)
468 {
469 unsigned int status, delta;
470 struct amba_icount *icount = &info->state->icount;
471
472 status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY;
473
474 delta = status ^ info->old_status;
475 info->old_status = status;
476
477 if (!delta)
478 return;
479
480 if (delta & AMBA_UARTFR_DCD) {
481 icount->dcd++;
482 #ifdef CONFIG_HARD_PPS
483 if ((info->flags & ASYNC_HARDPPS_CD) &&
484 (status & AMBA_UARTFR_DCD)
485 hardpps();
486 #endif
487 if (info->flags & ASYNC_CHECK_CD) {
488 if (status & AMBA_UARTFR_DCD)
489 wake_up_interruptible(&info->open_wait);
490 else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
491 (info->flags & ASYNC_CALLOUT_NOHUP))) {
492 if (info->tty)
493 tty_hangup(info->tty);
494 }
495 }
496 }
497
498 if (delta & AMBA_UARTFR_DSR)
499 icount->dsr++;
500
501 if (delta & AMBA_UARTFR_CTS) {
502 icount->cts++;
503
504 if (info->flags & ASYNC_CTS_FLOW) {
505 status &= AMBA_UARTFR_CTS;
506
507 if (info->tty->hw_stopped) {
508 if (status) {
509 info->tty->hw_stopped = 0;
510 ambauart_enable_tx_interrupt(info);
511 ambauart_event(info, EVT_WRITE_WAKEUP);
512 }
513 } else {
514 if (!status) {
515 info->tty->hw_stopped = 1;
516 ambauart_disable_tx_interrupt(info);
517 }
518 }
519 }
520 }
521 wake_up_interruptible(&info->delta_msr_wait);
522
523 }
524
525 static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
526 {
527 struct amba_info *info = dev_id;
528 unsigned int status, pass_counter = 0;
529
530 #if DEBUG_LEDS
531 // tell the world
532 set_leds(get_leds() | RED_LED);
533 #endif
534
535 status = UART_GET_INT_STATUS(info->port);
536 do {
537 /*
538 * FIXME: what about clearing the interrupts?
539 */
540
541 if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS))
542 #ifdef SUPPORT_SYSRQ
543 ambauart_rx_chars(info, regs);
544 #else
545 ambauart_rx_chars(info);
546 #endif
547 if (status & AMBA_UARTIIR_TIS)
548 ambauart_tx_chars(info);
549 if (status & AMBA_UARTIIR_MIS)
550 ambauart_modem_status(info);
551 if (pass_counter++ > AMBA_ISR_PASS_LIMIT)
552 break;
553
554 status = UART_GET_INT_STATUS(info->port);
555 } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS | AMBA_UARTIIR_TIS));
556
557 #if DEBUG_LEDS
558 // tell the world
559 set_leds(get_leds() & ~RED_LED);
560 #endif
561 }
562
563 static void ambauart_tasklet_action(unsigned long data)
564 {
565 struct amba_info *info = (struct amba_info *)data;
566 struct tty_struct *tty;
567
568 tty = info->tty;
569 if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event))
570 return;
571
572 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
573 tty->ldisc.write_wakeup)
574 (tty->ldisc.write_wakeup)(tty);
575 wake_up_interruptible(&tty->write_wait);
576 }
577
578 static int ambauart_startup(struct amba_info *info)
579 {
580 unsigned long flags;
581 unsigned long page;
582 int retval = 0;
583
584 page = get_zeroed_page(GFP_KERNEL);
585 if (!page)
586 return -ENOMEM;
587
588 save_flags(flags); cli();
589
590 if (info->flags & ASYNC_INITIALIZED) {
591 free_page(page);
592 goto errout;
593 }
594
595 if (info->xmit.buf)
596 free_page(page);
597 else
598 info->xmit.buf = (unsigned char *) page;
599
600 /*
601 * Allocate the IRQ
602 */
603 retval = request_irq(info->port->irq, ambauart_int, 0, "amba", info);
604 if (retval) {
605 if (capable(CAP_SYS_ADMIN)) {
606 if (info->tty)
607 set_bit(TTY_IO_ERROR, &info->tty->flags);
608 retval = 0;
609 }
610 goto errout;
611 }
612
613 info->mctrl = 0;
614 if (info->tty->termios->c_cflag & CBAUD)
615 info->mctrl = TIOCM_RTS | TIOCM_DTR;
616 info->port->set_mctrl(info->port, info->mctrl);
617
618 /*
619 * initialise the old status of the modem signals
620 */
621 info->old_status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY;
622
623 /*
624 * Finally, enable interrupts
625 */
626 ambauart_enable_rx_interrupt(info);
627
628 if (info->tty)
629 clear_bit(TTY_IO_ERROR, &info->tty->flags);
630 info->xmit.head = info->xmit.tail = 0;
631
632 /*
633 * Set up the tty->alt_speed kludge
634 */
635 if (info->tty) {
636 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
637 info->tty->alt_speed = 57600;
638 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
639 info->tty->alt_speed = 115200;
640 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
641 info->tty->alt_speed = 230400;
642 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
643 info->tty->alt_speed = 460800;
644 }
645
646 /*
647 * and set the speed of the serial port
648 */
649 ambauart_change_speed(info, 0);
650
651 info->flags |= ASYNC_INITIALIZED;
652 restore_flags(flags);
653 return 0;
654
655 errout:
656 restore_flags(flags);
657 return retval;
658 }
659
660 /*
661 * This routine will shutdown a serial port; interrupts are disabled, and
662 * DTR is dropped if the hangup on close termio flag is on.
663 */
664 static void ambauart_shutdown(struct amba_info *info)
665 {
666 unsigned long flags;
667
668 if (!(info->flags & ASYNC_INITIALIZED))
669 return;
670
671 save_flags(flags); cli(); /* Disable interrupts */
672
673 /*
674 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
675 * here so the queue might never be woken up
676 */
677 wake_up_interruptible(&info->delta_msr_wait);
678
679 /*
680 * Free the IRQ
681 */
682 free_irq(info->port->irq, info);
683
684 if (info->xmit.buf) {
685 unsigned long pg = (unsigned long) info->xmit.buf;
686 info->xmit.buf = NULL;
687 free_page(pg);
688 }
689
690 /*
691 * disable all interrupts, disable the port
692 */
693 UART_PUT_CR(info->port, 0);
694
695 /* disable break condition and fifos */
696 UART_PUT_LCRH(info->port, UART_GET_LCRH(info->port) &
697 ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
698
699 if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
700 info->mctrl &= ~(TIOCM_DTR|TIOCM_RTS);
701 info->port->set_mctrl(info->port, info->mctrl);
702
703 /* kill off our tasklet */
704 tasklet_kill(&info->tlet);
705 if (info->tty)
706 set_bit(TTY_IO_ERROR, &info->tty->flags);
707
708 info->flags &= ~ASYNC_INITIALIZED;
709 restore_flags(flags);
710 }
711
712 static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios)
713 {
714 unsigned int lcr_h, baud, quot, cflag, old_cr, bits;
715 unsigned long flags;
716
717 if (!info->tty || !info->tty->termios)
718 return;
719
720 cflag = info->tty->termios->c_cflag;
721
722 #if DEBUG
723 printk("ambauart_set_cflag(0x%x) called\n", cflag);
724 #endif
725 /* byte size and parity */
726 switch (cflag & CSIZE) {
727 case CS5: lcr_h = AMBA_UARTLCR_H_WLEN_5; bits = 7; break;
728 case CS6: lcr_h = AMBA_UARTLCR_H_WLEN_6; bits = 8; break;
729 case CS7: lcr_h = AMBA_UARTLCR_H_WLEN_7; bits = 9; break;
730 default: lcr_h = AMBA_UARTLCR_H_WLEN_8; bits = 10; break; // CS8
731 }
732 if (cflag & CSTOPB) {
733 lcr_h |= AMBA_UARTLCR_H_STP2;
734 bits ++;
735 }
736 if (cflag & PARENB) {
737 lcr_h |= AMBA_UARTLCR_H_PEN;
738 bits++;
739 if (!(cflag & PARODD))
740 lcr_h |= AMBA_UARTLCR_H_EPS;
741 }
742 if (info->port->fifosize > 1)
743 lcr_h |= AMBA_UARTLCR_H_FEN;
744
745 do {
746 /* Determine divisor based on baud rate */
747 baud = tty_get_baud_rate(info->tty);
748 if (!baud)
749 baud = 9600;
750
751 if (baud == 38400 &&
752 ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
753 quot = info->state->custom_divisor;
754 else
755 quot = (info->port->uartclk / (16 * baud)) - 1;
756
757 if (!quot && old_termios) {
758 info->tty->termios->c_cflag &= ~CBAUD;
759 info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
760 old_termios = NULL;
761 }
762 } while (quot == 0 && old_termios);
763
764 /* As a last resort, if the quotient is zero, default to 9600 bps */
765 if (!quot)
766 quot = (info->port->uartclk / (16 * 9600)) - 1;
767
768 info->timeout = (info->port->fifosize * HZ * bits * quot) /
769 (info->port->uartclk / 16);
770 info->timeout += HZ/50; /* Add .02 seconds of slop */
771
772 if (cflag & CRTSCTS)
773 info->flags |= ASYNC_CTS_FLOW;
774 else
775 info->flags &= ~ASYNC_CTS_FLOW;
776 if (cflag & CLOCAL)
777 info->flags &= ~ASYNC_CHECK_CD;
778 else
779 info->flags |= ASYNC_CHECK_CD;
780
781 /*
782 * Set up parity check flag
783 */
784 #define RELEVENT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
785
786 info->read_status_mask = AMBA_UARTRSR_OE;
787 if (I_INPCK(info->tty))
788 info->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
789 if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
790 info->read_status_mask |= AMBA_UARTRSR_BE;
791
792 /*
793 * Characters to ignore
794 */
795 info->ignore_status_mask = 0;
796 if (I_IGNPAR(info->tty))
797 info->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
798 if (I_IGNBRK(info->tty)) {
799 info->ignore_status_mask |= AMBA_UARTRSR_BE;
800 /*
801 * If we're ignoring parity and break indicators,
802 * ignore overruns to (for real raw support).
803 */
804 if (I_IGNPAR(info->tty))
805 info->ignore_status_mask |= AMBA_UARTRSR_OE;
806 }
807
808 /* first, disable everything */
809 save_flags(flags); cli();
810 old_cr = UART_GET_CR(info->port) &= ~AMBA_UARTCR_MSIE;
811
812 if ((info->flags & ASYNC_HARDPPS_CD) ||
813 (cflag & CRTSCTS) ||
814 !(cflag & CLOCAL))
815 old_cr |= AMBA_UARTCR_MSIE;
816
817 UART_PUT_CR(info->port, 0);
818 restore_flags(flags);
819
820 /* Set baud rate */
821 UART_PUT_LCRM(info->port, ((quot & 0xf00) >> 8));
822 UART_PUT_LCRL(info->port, (quot & 0xff));
823
824 /*
825 * ----------v----------v----------v----------v-----
826 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
827 * ----------^----------^----------^----------^-----
828 */
829 UART_PUT_LCRH(info->port, lcr_h);
830 UART_PUT_CR(info->port, old_cr);
831 }
832
833 static void ambauart_put_char(struct tty_struct *tty, u_char ch)
834 {
835 struct amba_info *info = tty->driver_data;
836 unsigned long flags;
837
838 if (!tty || !info->xmit.buf)
839 return;
840
841 save_flags(flags); cli();
842 if (CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE) != 0) {
843 info->xmit.buf[info->xmit.head] = ch;
844 info->xmit.head = (info->xmit.head + 1) & (AMBA_XMIT_SIZE - 1);
845 }
846 restore_flags(flags);
847 }
848
849 static void ambauart_flush_chars(struct tty_struct *tty)
850 {
851 struct amba_info *info = tty->driver_data;
852 unsigned long flags;
853
854 if (info->xmit.head == info->xmit.tail
855 || tty->stopped
856 || tty->hw_stopped
857 || !info->xmit.buf)
858 return;
859
860 save_flags(flags); cli();
861 ambauart_enable_tx_interrupt(info);
862 restore_flags(flags);
863 }
864
865 static int ambauart_write(struct tty_struct *tty, int from_user,
866 const u_char * buf, int count)
867 {
868 struct amba_info *info = tty->driver_data;
869 unsigned long flags;
870 int c, ret = 0;
871
872 if (!tty || !info->xmit.buf || !tmp_buf)
873 return 0;
874
875 save_flags(flags);
876 if (from_user) {
877 down(&tmp_buf_sem);
878 while (1) {
879 int c1;
880 c = CIRC_SPACE_TO_END(info->xmit.head,
881 info->xmit.tail,
882 AMBA_XMIT_SIZE);
883 if (count < c)
884 c = count;
885 if (c <= 0)
886 break;
887
888 c -= copy_from_user(tmp_buf, buf, c);
889 if (!c) {
890 if (!ret)
891 ret = -EFAULT;
892 break;
893 }
894 cli();
895 c1 = CIRC_SPACE_TO_END(info->xmit.head,
896 info->xmit.tail,
897 AMBA_XMIT_SIZE);
898 if (c1 < c)
899 c = c1;
900 memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
901 info->xmit.head = (info->xmit.head + c) &
902 (AMBA_XMIT_SIZE - 1);
903 restore_flags(flags);
904 buf += c;
905 count -= c;
906 ret += c;
907 }
908 up(&tmp_buf_sem);
909 } else {
910 cli();
911 while (1) {
912 c = CIRC_SPACE_TO_END(info->xmit.head,
913 info->xmit.tail,
914 AMBA_XMIT_SIZE);
915 if (count < c)
916 c = count;
917 if (c <= 0)
918 break;
919 memcpy(info->xmit.buf + info->xmit.head, buf, c);
920 info->xmit.head = (info->xmit.head + c) &
921 (AMBA_XMIT_SIZE - 1);
922 buf += c;
923 count -= c;
924 ret += c;
925 }
926 restore_flags(flags);
927 }
928 if (info->xmit.head != info->xmit.tail
929 && !tty->stopped
930 && !tty->hw_stopped)
931 ambauart_enable_tx_interrupt(info);
932 return ret;
933 }
934
935 static int ambauart_write_room(struct tty_struct *tty)
936 {
937 struct amba_info *info = tty->driver_data;
938
939 return CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE);
940 }
941
942 static int ambauart_chars_in_buffer(struct tty_struct *tty)
943 {
944 struct amba_info *info = tty->driver_data;
945
946 return CIRC_CNT(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE);
947 }
948
949 static void ambauart_flush_buffer(struct tty_struct *tty)
950 {
951 struct amba_info *info = tty->driver_data;
952 unsigned long flags;
953
954 #if DEBUG
955 printk("ambauart_flush_buffer(%d) called\n",
956 MINOR(tty->device) - tty->driver.minor_start);
957 #endif
958 save_flags(flags); cli();
959 info->xmit.head = info->xmit.tail = 0;
960 restore_flags(flags);
961 wake_up_interruptible(&tty->write_wait);
962 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
963 tty->ldisc.write_wakeup)
964 (tty->ldisc.write_wakeup)(tty);
965 }
966
967 /*
968 * This function is used to send a high-priority XON/XOFF character to
969 * the device
970 */
971 static void ambauart_send_xchar(struct tty_struct *tty, char ch)
972 {
973 struct amba_info *info = tty->driver_data;
974
975 info->x_char = ch;
976 if (ch)
977 ambauart_enable_tx_interrupt(info);
978 }
979
980 static void ambauart_throttle(struct tty_struct *tty)
981 {
982 struct amba_info *info = tty->driver_data;
983 unsigned long flags;
984
985 if (I_IXOFF(tty))
986 ambauart_send_xchar(tty, STOP_CHAR(tty));
987
988 if (tty->termios->c_cflag & CRTSCTS) {
989 save_flags(flags); cli();
990 info->mctrl &= ~TIOCM_RTS;
991 info->port->set_mctrl(info->port, info->mctrl);
992 restore_flags(flags);
993 }
994 }
995
996 static void ambauart_unthrottle(struct tty_struct *tty)
997 {
998 struct amba_info *info = (struct amba_info *) tty->driver_data;
999 unsigned long flags;
1000
1001 if (I_IXOFF(tty)) {
1002 if (info->x_char)
1003 info->x_char = 0;
1004 else
1005 ambauart_send_xchar(tty, START_CHAR(tty));
1006 }
1007
1008 if (tty->termios->c_cflag & CRTSCTS) {
1009 save_flags(flags); cli();
1010 info->mctrl |= TIOCM_RTS;
1011 info->port->set_mctrl(info->port, info->mctrl);
1012 restore_flags(flags);
1013 }
1014 }
1015
1016 static int get_serial_info(struct amba_info *info, struct serial_struct *retinfo)
1017 {
1018 struct amba_state *state = info->state;
1019 struct amba_port *port = info->port;
1020 struct serial_struct tmp;
1021
1022 memset(&tmp, 0, sizeof(tmp));
1023 tmp.type = 0;
1024 tmp.line = state->line;
1025 tmp.port = port->uart_base;
1026 if (HIGH_BITS_OFFSET)
1027 tmp.port_high = port->uart_base >> HIGH_BITS_OFFSET;
1028 tmp.irq = port->irq;
1029 tmp.flags = 0;
1030 tmp.xmit_fifo_size = port->fifosize;
1031 tmp.baud_base = port->uartclk / 16;
1032 tmp.close_delay = state->close_delay;
1033 tmp.closing_wait = state->closing_wait;
1034 tmp.custom_divisor = state->custom_divisor;
1035
1036 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
1037 return -EFAULT;
1038 return 0;
1039 }
1040
1041 static int set_serial_info(struct amba_info *info,
1042 struct serial_struct *newinfo)
1043 {
1044 struct serial_struct new_serial;
1045 struct amba_state *state, old_state;
1046 struct amba_port *port;
1047 unsigned long new_port;
1048 unsigned int i, change_irq, change_port;
1049 int retval = 0;
1050
1051 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
1052 return -EFAULT;
1053
1054 state = info->state;
1055 old_state = *state;
1056 port = info->port;
1057
1058 new_port = new_serial.port;
1059 if (HIGH_BITS_OFFSET)
1060 new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
1061
1062 change_irq = new_serial.irq != port->irq;
1063 change_port = new_port != port->uart_base;
1064
1065 if (!capable(CAP_SYS_ADMIN)) {
1066 if (change_irq || change_port ||
1067 (new_serial.baud_base != port->uartclk / 16) ||
1068 (new_serial.close_delay != state->close_delay) ||
1069 (new_serial.xmit_fifo_size != port->fifosize) ||
1070 ((new_serial.flags & ~ASYNC_USR_MASK) !=
1071 (state->flags & ~ASYNC_USR_MASK)))
1072 return -EPERM;
1073 state->flags = ((state->flags & ~ASYNC_USR_MASK) |
1074 (new_serial.flags & ASYNC_USR_MASK));
1075 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1076 (new_serial.flags & ASYNC_USR_MASK));
1077 state->custom_divisor = new_serial.custom_divisor;
1078 goto check_and_exit;
1079 }
1080
1081 if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
1082 (new_serial.baud_base < 9600))
1083 return -EINVAL;
1084
1085 if (new_serial.type && change_port) {
1086 for (i = 0; i < SERIAL_AMBA_NR; i++)
1087 if ((port != amba_ports + i) &&
1088 amba_ports[i].uart_base != new_port)
1089 return -EADDRINUSE;
1090 }
1091
1092 if ((change_port || change_irq) && (state->count > 1))
1093 return -EBUSY;
1094
1095 /*
1096 * OK, past this point, all the error checking has been done.
1097 * At this point, we start making changes.....
1098 */
1099 port->uartclk = new_serial.baud_base * 16;
1100 state->flags = ((state->flags & ~ASYNC_FLAGS) |
1101 (new_serial.flags & ASYNC_FLAGS));
1102 info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
1103 (info->flags & ASYNC_INTERNAL_FLAGS));
1104 state->custom_divisor = new_serial.custom_divisor;
1105 state->close_delay = new_serial.close_delay * HZ / 100;
1106 state->closing_wait = new_serial.closing_wait * HZ / 100;
1107 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1108 port->fifosize = new_serial.xmit_fifo_size;
1109
1110 if (change_port || change_irq) {
1111 /*
1112 * We need to shutdown the serial port at the old
1113 * port/irq combination.
1114 */
1115 ambauart_shutdown(info);
1116 port->irq = new_serial.irq;
1117 port->uart_base = new_port;
1118 }
1119
1120 check_and_exit:
1121 if (!port->uart_base)
1122 return 0;
1123 if (info->flags & ASYNC_INITIALIZED) {
1124 if ((old_state.flags & ASYNC_SPD_MASK) !=
1125 (state->flags & ASYNC_SPD_MASK) ||
1126 (old_state.custom_divisor != state->custom_divisor)) {
1127 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1128 info->tty->alt_speed = 57600;
1129 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1130 info->tty->alt_speed = 115200;
1131 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
1132 info->tty->alt_speed = 230400;
1133 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
1134 info->tty->alt_speed = 460800;
1135 ambauart_change_speed(info, NULL);
1136 }
1137 } else
1138 retval = ambauart_startup(info);
1139 return retval;
1140 }
1141
1142
1143 /*
1144 * get_lsr_info - get line status register info
1145 */
1146 static int get_lsr_info(struct amba_info *info, unsigned int *value)
1147 {
1148 unsigned int result, status;
1149 unsigned long flags;
1150
1151 save_flags(flags); cli();
1152 status = UART_GET_FR(info->port);
1153 restore_flags(flags);
1154 result = status & AMBA_UARTFR_BUSY ? TIOCSER_TEMT : 0;
1155
1156 /*
1157 * If we're about to load something into the transmit
1158 * register, we'll pretend the transmitter isn't empty to
1159 * avoid a race condition (depending on when the transmit
1160 * interrupt happens).
1161 */
1162 if (info->x_char ||
1163 ((CIRC_CNT(info->xmit.head, info->xmit.tail,
1164 AMBA_XMIT_SIZE) > 0) &&
1165 !info->tty->stopped && !info->tty->hw_stopped))
1166 result &= TIOCSER_TEMT;
1167
1168 return put_user(result, value);
1169 }
1170
1171 static int get_modem_info(struct amba_info *info, unsigned int *value)
1172 {
1173 unsigned int result = info->mctrl;
1174 unsigned int status;
1175
1176 status = UART_GET_FR(info->port);
1177 if (status & AMBA_UARTFR_DCD)
1178 result |= TIOCM_CAR;
1179 if (status & AMBA_UARTFR_DSR)
1180 result |= TIOCM_DSR;
1181 if (status & AMBA_UARTFR_CTS)
1182 result |= TIOCM_CTS;
1183
1184 return put_user(result, value);
1185 }
1186
1187 static int set_modem_info(struct amba_info *info, unsigned int cmd,
1188 unsigned int *value)
1189 {
1190 unsigned int arg, old;
1191 unsigned long flags;
1192
1193 if (get_user(arg, value))
1194 return -EFAULT;
1195
1196 old = info->mctrl;
1197 switch (cmd) {
1198 case TIOCMBIS:
1199 info->mctrl |= arg;
1200 break;
1201
1202 case TIOCMBIC:
1203 info->mctrl &= ~arg;
1204 break;
1205
1206 case TIOCMSET:
1207 info->mctrl = arg;
1208 break;
1209
1210 default:
1211 return -EINVAL;
1212 }
1213 save_flags(flags); cli();
1214 if (old != info->mctrl)
1215 info->port->set_mctrl(info->port, info->mctrl);
1216 restore_flags(flags);
1217 return 0;
1218 }
1219
1220 static void ambauart_break_ctl(struct tty_struct *tty, int break_state)
1221 {
1222 struct amba_info *info = tty->driver_data;
1223 unsigned long flags;
1224 unsigned int lcr_h;
1225
1226 save_flags(flags); cli();
1227 lcr_h = UART_GET_LCRH(info->port);
1228 if (break_state == -1)
1229 lcr_h |= AMBA_UARTLCR_H_BRK;
1230 else
1231 lcr_h &= ~AMBA_UARTLCR_H_BRK;
1232 UART_PUT_LCRH(info->port, lcr_h);
1233 restore_flags(flags);
1234 }
1235
1236 static int ambauart_ioctl(struct tty_struct *tty, struct file *file,
1237 unsigned int cmd, unsigned long arg)
1238 {
1239 struct amba_info *info = tty->driver_data;
1240 struct amba_icount cprev, cnow;
1241 struct serial_icounter_struct icount;
1242 unsigned long flags;
1243
1244 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1245 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
1246 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
1247 if (tty->flags & (1 << TTY_IO_ERROR))
1248 return -EIO;
1249 }
1250
1251 switch (cmd) {
1252 case TIOCMGET:
1253 return get_modem_info(info, (unsigned int *)arg);
1254 case TIOCMBIS:
1255 case TIOCMBIC:
1256 case TIOCMSET:
1257 return set_modem_info(info, cmd, (unsigned int *)arg);
1258 case TIOCGSERIAL:
1259 return get_serial_info(info,
1260 (struct serial_struct *)arg);
1261 case TIOCSSERIAL:
1262 return set_serial_info(info,
1263 (struct serial_struct *)arg);
1264 case TIOCSERGETLSR: /* Get line status register */
1265 return get_lsr_info(info, (unsigned int *)arg);
1266 /*
1267 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
1268 * - mask passed in arg for lines of interest
1269 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
1270 * Caller should use TIOCGICOUNT to see which one it was
1271 */
1272 case TIOCMIWAIT:
1273 save_flags(flags); cli();
1274 /* note the counters on entry */
1275 cprev = info->state->icount;
1276 /* Force modem status interrupts on */
1277 UART_PUT_CR(info->port, UART_GET_CR(info->port) | AMBA_UARTCR_MSIE);
1278 restore_flags(flags);
1279 while (1) {
1280 interruptible_sleep_on(&info->delta_msr_wait);
1281 /* see if a signal did it */
1282 if (signal_pending(current))
1283 return -ERESTARTSYS;
1284 save_flags(flags); cli();
1285 cnow = info->state->icount; /* atomic copy */
1286 restore_flags(flags);
1287 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
1288 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
1289 return -EIO; /* no change => error */
1290 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
1291 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
1292 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
1293 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
1294 return 0;
1295 }
1296 cprev = cnow;
1297 }
1298 /* NOTREACHED */
1299
1300 /*
1301 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
1302 * Return: write counters to the user passed counter struct
1303 * NB: both 1->0 and 0->1 transitions are counted except for
1304 * RI where only 0->1 is counted.
1305 */
1306 case TIOCGICOUNT:
1307 save_flags(flags); cli();
1308 cnow = info->state->icount;
1309 restore_flags(flags);
1310 icount.cts = cnow.cts;
1311 icount.dsr = cnow.dsr;
1312 icount.rng = cnow.rng;
1313 icount.dcd = cnow.dcd;
1314 icount.rx = cnow.rx;
1315 icount.tx = cnow.tx;
1316 icount.frame = cnow.frame;
1317 icount.overrun = cnow.overrun;
1318 icount.parity = cnow.parity;
1319 icount.brk = cnow.brk;
1320 icount.buf_overrun = cnow.buf_overrun;
1321
1322 return copy_to_user((void *)arg, &icount, sizeof(icount))
1323 ? -EFAULT : 0;
1324
1325 default:
1326 return -ENOIOCTLCMD;
1327 }
1328 return 0;
1329 }
1330
1331 static void ambauart_set_termios(struct tty_struct *tty, struct termios *old_termios)
1332 {
1333 struct amba_info *info = tty->driver_data;
1334 unsigned long flags;
1335 unsigned int cflag = tty->termios->c_cflag;
1336
1337 if ((cflag ^ old_termios->c_cflag) == 0 &&
1338 RELEVENT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
1339 return;
1340
1341 ambauart_change_speed(info, old_termios);
1342
1343 /* Handle transition to B0 status */
1344 if ((old_termios->c_cflag & CBAUD) &&
1345 !(cflag & CBAUD)) {
1346 save_flags(flags); cli();
1347 info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR);
1348 info->port->set_mctrl(info->port, info->mctrl);
1349 restore_flags(flags);
1350 }
1351
1352 /* Handle transition away from B0 status */
1353 if (!(old_termios->c_cflag & CBAUD) &&
1354 (cflag & CBAUD)) {
1355 save_flags(flags); cli();
1356 info->mctrl |= TIOCM_DTR;
1357 if (!(cflag & CRTSCTS) ||
1358 !test_bit(TTY_THROTTLED, &tty->flags))
1359 info->mctrl |= TIOCM_RTS;
1360 info->port->set_mctrl(info->port, info->mctrl);
1361 restore_flags(flags);
1362 }
1363
1364 /* Handle turning off CRTSCTS */
1365 if ((old_termios->c_cflag & CRTSCTS) &&
1366 !(cflag & CRTSCTS)) {
1367 tty->hw_stopped = 0;
1368 ambauart_start(tty);
1369 }
1370
1371 #if 0
1372 /*
1373 * No need to wake up processes in open wait, since they
1374 * sample the CLOCAL flag once, and don't recheck it.
1375 * XXX It's not clear whether the current behavior is correct
1376 * or not. Hence, this may change.....
1377 */
1378 if (!(old_termios->c_cflag & CLOCAL) &&
1379 (tty->termios->c_cflag & CLOCAL))
1380 wake_up_interruptible(&info->open_wait);
1381 #endif
1382 }
1383
1384 static void ambauart_close(struct tty_struct *tty, struct file *filp)
1385 {
1386 struct amba_info *info = tty->driver_data;
1387 struct amba_state *state;
1388 unsigned long flags;
1389
1390 if (!info)
1391 return;
1392
1393 state = info->state;
1394
1395 #if DEBUG
1396 printk("ambauart_close() called\n");
1397 #endif
1398
1399 save_flags(flags); cli();
1400
1401 if (tty_hung_up_p(filp)) {
1402 MOD_DEC_USE_COUNT;
1403 restore_flags(flags);
1404 return;
1405 }
1406
1407 if ((tty->count == 1) && (state->count != 1)) {
1408 /*
1409 * Uh, oh. tty->count is 1, which means that the tty
1410 * structure will be freed. state->count should always
1411 * be one in these conditions. If it's greater than
1412 * one, we've got real problems, since it means the
1413 * serial port won't be shutdown.
1414 */
1415 printk("ambauart_close: bad serial port count; tty->count is 1, "
1416 "state->count is %d\n", state->count);
1417 state->count = 1;
1418 }
1419 if (--state->count < 0) {
1420 printk("rs_close: bad serial port count for %s%d: %d\n",
1421 tty->driver.name, info->state->line, state->count);
1422 state->count = 0;
1423 }
1424 if (state->count) {
1425 MOD_DEC_USE_COUNT;
1426 restore_flags(flags);
1427 return;
1428 }
1429 info->flags |= ASYNC_CLOSING;
1430 restore_flags(flags);
1431 /*
1432 * Save the termios structure, since this port may have
1433 * separate termios for callout and dialin.
1434 */
1435 if (info->flags & ASYNC_NORMAL_ACTIVE)
1436 info->state->normal_termios = *tty->termios;
1437 if (info->flags & ASYNC_CALLOUT_ACTIVE)
1438 info->state->callout_termios = *tty->termios;
1439 /*
1440 * Now we wait for the transmit buffer to clear; and we notify
1441 * the line discipline to only process XON/XOFF characters.
1442 */
1443 tty->closing = 1;
1444 if (info->state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1445 tty_wait_until_sent(tty, info->state->closing_wait);
1446 /*
1447 * At this point, we stop accepting input. To do this, we
1448 * disable the receive line status interrupts.
1449 */
1450 if (info->flags & ASYNC_INITIALIZED) {
1451 ambauart_disable_rx_interrupt(info);
1452 /*
1453 * Before we drop DTR, make sure the UART transmitter
1454 * has completely drained; this is especially
1455 * important if there is a transmit FIFO!
1456 */
1457 ambauart_wait_until_sent(tty, info->timeout);
1458 }
1459 ambauart_shutdown(info);
1460 if (tty->driver.flush_buffer)
1461 tty->driver.flush_buffer(tty);
1462 if (tty->ldisc.flush_buffer)
1463 tty->ldisc.flush_buffer(tty);
1464 tty->closing = 0;
1465 info->event = 0;
1466 info->tty = NULL;
1467 if (info->blocked_open) {
1468 if (info->state->close_delay) {
1469 set_current_state(TASK_INTERRUPTIBLE);
1470 schedule_timeout(info->state->close_delay);
1471 }
1472 wake_up_interruptible(&info->open_wait);
1473 }
1474 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
1475 ASYNC_CLOSING);
1476 wake_up_interruptible(&info->close_wait);
1477 MOD_DEC_USE_COUNT;
1478 }
1479
1480 static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout)
1481 {
1482 struct amba_info *info = (struct amba_info *) tty->driver_data;
1483 unsigned long char_time, expire;
1484 unsigned int status;
1485
1486 if (info->port->fifosize == 0)
1487 return;
1488
1489 /*
1490 * Set the check interval to be 1/5 of the estimated time to
1491 * send a single character, and make it at least 1. The check
1492 * interval should also be less than the timeout.
1493 *
1494 * Note: we have to use pretty tight timings here to satisfy
1495 * the NIST-PCTS.
1496 */
1497 char_time = (info->timeout - HZ/50) / info->port->fifosize;
1498 char_time = char_time / 5;
1499 if (char_time == 0)
1500 char_time = 1;
1501 if (timeout && timeout < char_time)
1502 char_time = timeout;
1503 /*
1504 * If the transmitter hasn't cleared in twice the approximate
1505 * amount of time to send the entire FIFO, it probably won't
1506 * ever clear. This assumes the UART isn't doing flow
1507 * control, which is currently the case. Hence, if it ever
1508 * takes longer than info->timeout, this is probably due to a
1509 * UART bug of some kind. So, we clamp the timeout parameter at
1510 * 2*info->timeout.
1511 */
1512 if (!timeout || timeout > 2 * info->timeout)
1513 timeout = 2 * info->timeout;
1514
1515 expire = jiffies + timeout;
1516 #if DEBUG
1517 printk("ambauart_wait_until_sent(%d), jiff=%lu, expire=%lu...\n",
1518 MINOR(tty->device) - tty->driver.minor_start, jiffies,
1519 expire);
1520 #endif
1521 while (UART_GET_FR(info->port) & AMBA_UARTFR_BUSY) {
1522 set_current_state(TASK_INTERRUPTIBLE);
1523 schedule_timeout(char_time);
1524 if (signal_pending(current))
1525 break;
1526 if (timeout && time_after(jiffies, expire))
1527 break;
1528 status = UART_GET_FR(info->port);
1529 }
1530 set_current_state(TASK_RUNNING);
1531 }
1532
1533 static void ambauart_hangup(struct tty_struct *tty)
1534 {
1535 struct amba_info *info = tty->driver_data;
1536 struct amba_state *state = info->state;
1537
1538 ambauart_flush_buffer(tty);
1539 if (info->flags & ASYNC_CLOSING)
1540 return;
1541 ambauart_shutdown(info);
1542 info->event = 0;
1543 state->count = 0;
1544 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
1545 info->tty = NULL;
1546 wake_up_interruptible(&info->open_wait);
1547 }
1548
1549 static int block_til_ready(struct tty_struct *tty, struct file *filp,
1550 struct amba_info *info)
1551 {
1552 DECLARE_WAITQUEUE(wait, current);
1553 struct amba_state *state = info->state;
1554 unsigned long flags;
1555 int do_clocal = 0, extra_count = 0, retval;
1556
1557 /*
1558 * If the device is in the middle of being closed, then block
1559 * until it's done, and then try again.
1560 */
1561 if (tty_hung_up_p(filp) ||
1562 (info->flags & ASYNC_CLOSING)) {
1563 if (info->flags & ASYNC_CLOSING)
1564 interruptible_sleep_on(&info->close_wait);
1565 return (info->flags & ASYNC_HUP_NOTIFY) ?
1566 -EAGAIN : -ERESTARTSYS;
1567 }
1568
1569 /*
1570 * If this is a callout device, then just make sure the normal
1571 * device isn't being used.
1572 */
1573 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
1574 if (info->flags & ASYNC_NORMAL_ACTIVE)
1575 return -EBUSY;
1576 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
1577 (info->flags & ASYNC_SESSION_LOCKOUT) &&
1578 (info->session != current->session))
1579 return -EBUSY;
1580 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
1581 (info->flags & ASYNC_PGRP_LOCKOUT) &&
1582 (info->pgrp != current->pgrp))
1583 return -EBUSY;
1584 info->flags |= ASYNC_CALLOUT_ACTIVE;
1585 return 0;
1586 }
1587
1588 /*
1589 * If non-blocking mode is set, or the port is not enabled,
1590 * then make the check up front and then exit.
1591 */
1592 if ((filp->f_flags & O_NONBLOCK) ||
1593 (tty->flags & (1 << TTY_IO_ERROR))) {
1594 if (info->flags & ASYNC_CALLOUT_ACTIVE)
1595 return -EBUSY;
1596 info->flags |= ASYNC_NORMAL_ACTIVE;
1597 return 0;
1598 }
1599
1600 if (info->flags & ASYNC_CALLOUT_ACTIVE) {
1601 if (state->normal_termios.c_cflag & CLOCAL)
1602 do_clocal = 1;
1603 } else {
1604 if (tty->termios->c_cflag & CLOCAL)
1605 do_clocal = 1;
1606 }
1607
1608 /*
1609 * Block waiting for the carrier detect and the line to become
1610 * free (i.e., not in use by the callout). While we are in
1611 * this loop, state->count is dropped by one, so that
1612 * rs_close() knows when to free things. We restore it upon
1613 * exit, either normal or abnormal.
1614 */
1615 retval = 0;
1616 add_wait_queue(&info->open_wait, &wait);
1617 save_flags(flags); cli();
1618 if (!tty_hung_up_p(filp)) {
1619 extra_count = 1;
1620 state->count--;
1621 }
1622 restore_flags(flags);
1623 info->blocked_open++;
1624 while (1) {
1625 save_flags(flags); cli();
1626 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
1627 (tty->termios->c_cflag & CBAUD)) {
1628 info->mctrl = TIOCM_DTR | TIOCM_RTS;
1629 info->port->set_mctrl(info->port, info->mctrl);
1630 }
1631 restore_flags(flags);
1632 set_current_state(TASK_INTERRUPTIBLE);
1633 if (tty_hung_up_p(filp) ||
1634 !(info->flags & ASYNC_INITIALIZED)) {
1635 if (info->flags & ASYNC_HUP_NOTIFY)
1636 retval = -EAGAIN;
1637 else
1638 retval = -ERESTARTSYS;
1639 break;
1640 }
1641 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
1642 !(info->flags & ASYNC_CLOSING) &&
1643 (do_clocal || (UART_GET_FR(info->port) & AMBA_UARTFR_DCD)))
1644 break;
1645 if (signal_pending(current)) {
1646 retval = -ERESTARTSYS;
1647 break;
1648 }
1649 schedule();
1650 }
1651 set_current_state(TASK_RUNNING);
1652 remove_wait_queue(&info->open_wait, &wait);
1653 if (extra_count)
1654 state->count++;
1655 info->blocked_open--;
1656 if (retval)
1657 return retval;
1658 info->flags |= ASYNC_NORMAL_ACTIVE;
1659 return 0;
1660 }
1661
1662 static struct amba_info *ambauart_get(int line)
1663 {
1664 struct amba_info *info;
1665 struct amba_state *state = amba_state + line;
1666
1667 state->count++;
1668 if (state->info)
1669 return state->info;
1670 info = kmalloc(sizeof(struct amba_info), GFP_KERNEL);
1671 if (info) {
1672 memset(info, 0, sizeof(struct amba_info));
1673 init_waitqueue_head(&info->open_wait);
1674 init_waitqueue_head(&info->close_wait);
1675 init_waitqueue_head(&info->delta_msr_wait);
1676 info->flags = state->flags;
1677 info->state = state;
1678 info->port = amba_ports + line;
1679 tasklet_init(&info->tlet, ambauart_tasklet_action,
1680 (unsigned long)info);
1681 }
1682 if (state->info) {
1683 kfree(info);
1684 return state->info;
1685 }
1686 state->info = info;
1687 return info;
1688 }
1689
1690 static int ambauart_open(struct tty_struct *tty, struct file *filp)
1691 {
1692 struct amba_info *info;
1693 int retval, line = MINOR(tty->device) - tty->driver.minor_start;
1694
1695 #if DEBUG
1696 printk("ambauart_open(%d) called\n", line);
1697 #endif
1698
1699 // is this a line that we've got?
1700 MOD_INC_USE_COUNT;
1701 if (line >= SERIAL_AMBA_NR) {
1702 MOD_DEC_USE_COUNT;
1703 return -ENODEV;
1704 }
1705
1706 info = ambauart_get(line);
1707 if (!info)
1708 return -ENOMEM;
1709
1710 tty->driver_data = info;
1711 info->tty = tty;
1712 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1713
1714 /*
1715 * Make sure we have the temporary buffer allocated
1716 */
1717 if (!tmp_buf) {
1718 unsigned long page = get_zeroed_page(GFP_KERNEL);
1719 if (tmp_buf)
1720 free_page(page);
1721 else if (!page) {
1722 MOD_DEC_USE_COUNT;
1723 return -ENOMEM;
1724 }
1725 tmp_buf = (u_char *)page;
1726 }
1727
1728 /*
1729 * If the port is in the middle of closing, bail out now.
1730 */
1731 if (tty_hung_up_p(filp) ||
1732 (info->flags & ASYNC_CLOSING)) {
1733 if (info->flags & ASYNC_CLOSING)
1734 interruptible_sleep_on(&info->close_wait);
1735 MOD_DEC_USE_COUNT;
1736 return -EAGAIN;
1737 }
1738
1739 /*
1740 * Start up the serial port
1741 */
1742 retval = ambauart_startup(info);
1743 if (retval) {
1744 MOD_DEC_USE_COUNT;
1745 return retval;
1746 }
1747
1748 retval = block_til_ready(tty, filp, info);
1749 if (retval) {
1750 MOD_DEC_USE_COUNT;
1751 return retval;
1752 }
1753
1754 if ((info->state->count == 1) &&
1755 (info->flags & ASYNC_SPLIT_TERMIOS)) {
1756 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
1757 *tty->termios = info->state->normal_termios;
1758 else
1759 *tty->termios = info->state->callout_termios;
1760 }
1761 #ifdef CONFIG_SERIAL_AMBA_CONSOLE
1762 if (ambauart_cons.cflag && ambauart_cons.index == line) {
1763 tty->termios->c_cflag = ambauart_cons.cflag;
1764 ambauart_cons.cflag = 0;
1765 }
1766 #endif
1767 ambauart_change_speed(info, NULL);
1768 info->session = current->session;
1769 info->pgrp = current->pgrp;
1770 return 0;
1771 }
1772
1773 int __init ambauart_init(void)
1774 {
1775 int i;
1776
1777 ambanormal_driver.magic = TTY_DRIVER_MAGIC;
1778 ambanormal_driver.driver_name = "serial_amba";
1779 ambanormal_driver.name = SERIAL_AMBA_NAME;
1780 ambanormal_driver.major = SERIAL_AMBA_MAJOR;
1781 ambanormal_driver.minor_start = SERIAL_AMBA_MINOR;
1782 ambanormal_driver.num = SERIAL_AMBA_NR;
1783 ambanormal_driver.type = TTY_DRIVER_TYPE_SERIAL;
1784 ambanormal_driver.subtype = SERIAL_TYPE_NORMAL;
1785 ambanormal_driver.init_termios = tty_std_termios;
1786 ambanormal_driver.init_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
1787 ambanormal_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
1788 ambanormal_driver.refcount = &ambauart_refcount;
1789 ambanormal_driver.table = ambauart_table;
1790 ambanormal_driver.termios = ambauart_termios;
1791 ambanormal_driver.termios_locked = ambauart_termios_locked;
1792
1793 ambanormal_driver.open = ambauart_open;
1794 ambanormal_driver.close = ambauart_close;
1795 ambanormal_driver.write = ambauart_write;
1796 ambanormal_driver.put_char = ambauart_put_char;
1797 ambanormal_driver.flush_chars = ambauart_flush_chars;
1798 ambanormal_driver.write_room = ambauart_write_room;
1799 ambanormal_driver.chars_in_buffer = ambauart_chars_in_buffer;
1800 ambanormal_driver.flush_buffer = ambauart_flush_buffer;
1801 ambanormal_driver.ioctl = ambauart_ioctl;
1802 ambanormal_driver.throttle = ambauart_throttle;
1803 ambanormal_driver.unthrottle = ambauart_unthrottle;
1804 ambanormal_driver.send_xchar = ambauart_send_xchar;
1805 ambanormal_driver.set_termios = ambauart_set_termios;
1806 ambanormal_driver.stop = ambauart_stop;
1807 ambanormal_driver.start = ambauart_start;
1808 ambanormal_driver.hangup = ambauart_hangup;
1809 ambanormal_driver.break_ctl = ambauart_break_ctl;
1810 ambanormal_driver.wait_until_sent = ambauart_wait_until_sent;
1811 ambanormal_driver.read_proc = NULL;
1812
1813 /*
1814 * The callout device is just like the normal device except for
1815 * the major number and the subtype code.
1816 */
1817 ambacallout_driver = ambanormal_driver;
1818 ambacallout_driver.name = CALLOUT_AMBA_NAME;
1819 ambacallout_driver.major = CALLOUT_AMBA_MAJOR;
1820 ambacallout_driver.subtype = SERIAL_TYPE_CALLOUT;
1821 ambacallout_driver.read_proc = NULL;
1822 ambacallout_driver.proc_entry = NULL;
1823
1824 if (tty_register_driver(&ambanormal_driver))
1825 panic("Couldn't register AMBA serial driver\n");
1826 if (tty_register_driver(&ambacallout_driver))
1827 panic("Couldn't register AMBA callout driver\n");
1828
1829 for (i = 0; i < SERIAL_AMBA_NR; i++) {
1830 struct amba_state *state = amba_state + i;
1831 state->line = i;
1832 state->close_delay = 5 * HZ / 10;
1833 state->closing_wait = 30 * HZ;
1834 state->callout_termios = ambacallout_driver.init_termios;
1835 state->normal_termios = ambanormal_driver.init_termios;
1836 }
1837
1838 return 0;
1839 }
1840
1841 __initcall(ambauart_init);
1842
1843 #ifdef CONFIG_SERIAL_AMBA_CONSOLE
1844 /************** console driver *****************/
1845
1846 /*
1847 * This code is currently never used; console->read is never called.
1848 * Therefore, although we have an implementation, we don't use it.
1849 * FIXME: the "const char *s" should be fixed to "char *s" some day.
1850 * (when the definition in include/linux/console.h is also fixed)
1851 */
1852 #ifdef used_and_not_const_char_pointer
1853 static int ambauart_console_read(struct console *co, const char *s, u_int count)
1854 {
1855 struct amba_port *port = &amba_ports[co->index];
1856 unsigned int status;
1857 char *w;
1858 int c;
1859 #if DEBUG
1860 printk("ambauart_console_read() called\n");
1861 #endif
1862
1863 c = 0;
1864 w = s;
1865 while (c < count) {
1866 status = UART_GET_FR(port);
1867 if (UART_RX_DATA(status)) {
1868 *w++ = UART_GET_CHAR(port);
1869 c++;
1870 } else {
1871 // nothing more to get, return
1872 return c;
1873 }
1874 }
1875 // return the count
1876 return c;
1877 }
1878 #endif
1879
1880 /*
1881 * Print a string to the serial port trying not to disturb
1882 * any possible real use of the port...
1883 *
1884 * The console_lock must be held when we get here.
1885 */
1886 static void ambauart_console_write(struct console *co, const char *s, u_int count)
1887 {
1888 struct amba_port *port = &amba_ports[co->index];
1889 unsigned int status, old_cr;
1890 int i;
1891
1892 /*
1893 * First save the CR then disable the interrupts
1894 */
1895 old_cr = UART_GET_CR(port);
1896 UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
1897
1898 /*
1899 * Now, do each character
1900 */
1901 for (i = 0; i < count; i++) {
1902 do {
1903 status = UART_GET_FR(port);
1904 } while (!UART_TX_READY(status));
1905 UART_PUT_CHAR(port, s[i]);
1906 if (s[i] == '\n') {
1907 do {
1908 status = UART_GET_FR(port);
1909 } while (!UART_TX_READY(status));
1910 UART_PUT_CHAR(port, '\r');
1911 }
1912 }
1913
1914 /*
1915 * Finally, wait for transmitter to become empty
1916 * and restore the TCR
1917 */
1918 do {
1919 status = UART_GET_FR(port);
1920 } while (status & AMBA_UARTFR_BUSY);
1921 UART_PUT_CR(port, old_cr);
1922 }
1923
1924 /*
1925 * Receive character from the serial port
1926 */
1927 static int ambauart_console_wait_key(struct console *co)
1928 {
1929 struct amba_port *port = &amba_ports[co->index];
1930 unsigned int status;
1931 int c;
1932
1933 do {
1934 status = UART_GET_FR(port);
1935 } while (!UART_RX_DATA(status));
1936 c = UART_GET_CHAR(port);
1937 return c;
1938 }
1939
1940 static kdev_t ambauart_console_device(struct console *c)
1941 {
1942 return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + c->index);
1943 }
1944
1945 static int __init ambauart_console_setup(struct console *co, char *options)
1946 {
1947 struct amba_port *port;
1948 int baud = 38400;
1949 int bits = 8;
1950 int parity = 'n';
1951 u_int cflag = CREAD | HUPCL | CLOCAL;
1952 u_int lcr_h, quot;
1953
1954 if (co->index >= SERIAL_AMBA_NR)
1955 co->index = 0;
1956
1957 port = &amba_ports[co->index];
1958
1959 if (options) {
1960 char *s = options;
1961 baud = simple_strtoul(s, NULL, 10);
1962 while (*s >= '' && *s <= '9')
1963 s++;
1964 if (*s) parity = *s++;
1965 if (*s) bits = *s - '';
1966 }
1967
1968 /*
1969 * Now construct a cflag setting.
1970 */
1971 switch (baud) {
1972 case 1200: cflag |= B1200; break;
1973 case 2400: cflag |= B2400; break;
1974 case 4800: cflag |= B4800; break;
1975 default: cflag |= B9600; baud = 9600; break;
1976 case 19200: cflag |= B19200; break;
1977 case 38400: cflag |= B38400; break;
1978 case 57600: cflag |= B57600; break;
1979 case 115200: cflag |= B115200; break;
1980 }
1981 switch (bits) {
1982 case 7: cflag |= CS7; lcr_h = AMBA_UARTLCR_H_WLEN_7; break;
1983 default: cflag |= CS8; lcr_h = AMBA_UARTLCR_H_WLEN_8; break;
1984 }
1985 switch (parity) {
1986 case 'o':
1987 case 'O': cflag |= PARODD; lcr_h |= AMBA_UARTLCR_H_PEN; break;
1988 case 'e':
1989 case 'E': cflag |= PARENB; lcr_h |= AMBA_UARTLCR_H_PEN |
1990 AMBA_UARTLCR_H_EPS; break;
1991 }
1992
1993 co->cflag = cflag;
1994
1995 if (port->fifosize > 1)
1996 lcr_h |= AMBA_UARTLCR_H_FEN;
1997
1998 quot = (port->uartclk / (16 * baud)) - 1;
1999
2000 UART_PUT_LCRL(port, (quot & 0xff));
2001 UART_PUT_LCRM(port, (quot >> 8));
2002 UART_PUT_LCRH(port, lcr_h);
2003
2004 /* we will enable the port as we need it */
2005 UART_PUT_CR(port, 0);
2006
2007 return 0;
2008 }
2009
2010 static struct console ambauart_cons =
2011 {
2012 name: SERIAL_AMBA_NAME,
2013 write: ambauart_console_write,
2014 #ifdef used_and_not_const_char_pointer
2015 read: ambauart_console_read,
2016 #endif
2017 device: ambauart_console_device,
2018 wait_key: ambauart_console_wait_key,
2019 setup: ambauart_console_setup,
2020 flags: CON_PRINTBUFFER,
2021 index: -1,
2022 };
2023
2024 void __init ambauart_console_init(void)
2025 {
2026 register_console(&ambauart_cons);
2027 }
2028
2029 #endif /* CONFIG_SERIAL_AMBA_CONSOLE */
2030
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.