11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Driver for 8250/16550-type serial ports
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright (C) 2001 Russell King.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14bc49a661e6e82bfa8219c3d0a2e4dea51c847d23Russell King#include <linux/serial_8250.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16850624c15da4651f4c6b821723419d8777659577Paul Gortmakerstruct uart_8250_port {
17850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	struct uart_port	port;
18850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	struct timer_list	timer;		/* "no irq" timer */
19850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	struct list_head	list;		/* ports on this IRQ */
20850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned short		capabilities;	/* port capabilities */
21850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned short		bugs;		/* port bugs */
22850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned int		tx_loadsz;	/* transmit fifo load size */
23850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		acr;
24850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		ier;
25850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		lcr;
26850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		mcr;
27850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		mcr_mask;	/* mask of user bits */
28850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		mcr_force;	/* mask of forced bits */
29850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		cur_iotype;	/* Running I/O type */
30850624c15da4651f4c6b821723419d8777659577Paul Gortmaker
31850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	/*
32850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	 * Some bits in registers are cleared on a read, so they must
33850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	 * be saved whenever the register is read but the bits will not
34850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	 * be immediately processed.
35850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	 */
36850624c15da4651f4c6b821723419d8777659577Paul Gortmaker#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
37850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		lsr_saved_flags;
38850624c15da4651f4c6b821723419d8777659577Paul Gortmaker#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
39850624c15da4651f4c6b821723419d8777659577Paul Gortmaker	unsigned char		msr_saved_flags;
40850624c15da4651f4c6b821723419d8777659577Paul Gortmaker};
41850624c15da4651f4c6b821723419d8777659577Paul Gortmaker
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct old_serial_port {
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int uart;
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int baud_base;
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int port;
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int irq;
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int flags;
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char hub6;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char io_type;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char *iomem_base;
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned short iomem_reg_shift;
521c2f04937b3e397a5695953c6b82aa4c77d21eb8Vikram Pandita	unsigned long irqflags;
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This replaces serial_uart_config in include/linux/serial.h
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct serial8250_config {
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const char	*name;
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned short	fifo_size;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned short	tx_loadsz;
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char	fcr;
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int	flags;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UART_CAP_FIFO	(1 << 8)	/* UART has FIFO */
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UART_CAP_EFR	(1 << 9)	/* UART has EFR */
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UART_CAP_SLEEP	(1 << 10)	/* UART has IER sleep */
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UART_CAP_AFE	(1 << 11)	/* MCR-based hw flow control */
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UART_CAP_UUE	(1 << 12)	/* UART needs IER bit 6 set (Xscale) */
714539c24fe4f92c09ee668ef959d3e8180df619b9Stephen Warren#define UART_CAP_RTOIE	(1 << 13)	/* UART needs IER bit 4 set (Xscale, Tegra) */
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
734ba5e35daa90871fcb9b01f5ad1e5723343cc0a9Russell King#define UART_BUG_QUOT	(1 << 0)	/* UART has buggy quot LSB */
7455d3b282b90620e02e825304a9433732a84c58a5Russell King#define UART_BUG_TXEN	(1 << 1)	/* UART has buggy TX IIR status */
7521c614a7899046ab108b3d327d76c33443a8ebf2Pantelis Antoniou#define UART_BUG_NOMSR	(1 << 2)	/* UART has buggy MSR status bits (Au1x00) */
76363f66fe06c75270b669c88e321e6b354ba0201eWill Newton#define UART_BUG_THRE	(1 << 3)	/* UART has buggy THRE reassertion */
774ba5e35daa90871fcb9b01f5ad1e5723343cc0a9Russell King
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PROBE_RSA	(1 << 0)
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PROBE_ANY	(~0)
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SERIAL8250_SHARE_IRQS 1
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SERIAL8250_SHARE_IRQS 0
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
893f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmakerstatic inline int serial_in(struct uart_8250_port *up, int offset)
903f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker{
913f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker	return up->port.serial_in(&up->port, offset);
923f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker}
933f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker
943f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmakerstatic inline void serial_out(struct uart_8250_port *up, int offset, int value)
953f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker{
963f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker	up->port.serial_out(&up->port, offset, value);
973f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker}
983f0ab32753b49ae7afc5b69e3f23152d92aa1f85Paul Gortmaker
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(__alpha__) && !defined(CONFIG_PCI)
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Digital did something really horribly wrong with the OUT1 and OUT2
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * lines on at least some ALPHA's.  The failure mode is that if either
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is cleared, the machine locks up with endless interrupts.
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ALPHA_KLUDGE_MCR  (UART_MCR_OUT2 | UART_MCR_OUT1)
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#elif defined(CONFIG_SBC8560)
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WindRiver did something similarly broken on their SBC8560 board. The
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * UART tristates its IRQ output while OUT2 is clear, but they pulled
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the interrupt line _up_ instead of down, so if we register the IRQ
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * while the UART is in that state, we die in an IRQ storm. */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ALPHA_KLUDGE_MCR (UART_MCR_OUT2)
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ALPHA_KLUDGE_MCR 0
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
116