File: /usr/src/linux/drivers/char/serial_amba.c

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/slab.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 must be locked 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 >= '0' && *s <= '9')
1963     			s++;
1964     		if (*s) parity = *s++;
1965     		if (*s) bits = *s - '0';
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     
2031     MODULE_LICENSE("GPL");
2032     EXPORT_NO_SYMBOLS;
2033