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