| From 5df029e7baab27a7b6f848739659865a006820f9 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?S=C3=B8ren=20Holm?= <sgh@sgh.dk> |
| Date: Fri, 2 Sep 2011 22:55:37 +0200 |
| Subject: serial: Support the EFR-register of XR1715x uarts. |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| The EFR (Enhenced-Features-Register) is located at a different offset |
| than the other devices supporting UART_CAP_EFR. This change add a special |
| setup quick to set UPF_EXAR_EFR on the port. UPF_EXAR_EFR is then used to |
| the port type to PORT_XR17D15X since it is for sure a XR17D15X uart. |
| |
| Signed-off-by: SΓΈren Holm <sgh@sgh.dk> |
| Acked-by: Alan Cox <alan@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| (cherry picked from commit 06315348b16178e4c006e7892ef8e5e65f49c66a) |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| drivers/tty/serial/8250.c | 20 +++++++++++++++++++- |
| drivers/tty/serial/8250_pci.c | 33 +++++++++++++++++++++++++++++++++ |
| include/linux/serial_core.h | 4 +++- |
| include/linux/serial_reg.h | 1 + |
| 4 files changed, 56 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/tty/serial/8250.c |
| +++ b/drivers/tty/serial/8250.c |
| @@ -309,6 +309,13 @@ static const struct serial8250_config ua |
| UART_FCR_T_TRIG_01, |
| .flags = UART_CAP_FIFO | UART_CAP_RTOIE, |
| }, |
| + [PORT_XR17D15X] = { |
| + .name = "XR17D15X", |
| + .fifo_size = 64, |
| + .tx_loadsz = 64, |
| + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
| + .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, |
| + }, |
| }; |
| |
| #if defined(CONFIG_MIPS_ALCHEMY) |
| @@ -1052,6 +1059,14 @@ static void autoconfig_16550a(struct uar |
| serial_outp(up, UART_IER, iersave); |
| |
| /* |
| + * Exar uarts have EFR in a weird location |
| + */ |
| + if (up->port.flags & UPF_EXAR_EFR) { |
| + up->port.type = PORT_XR17D15X; |
| + up->capabilities |= UART_CAP_AFE | UART_CAP_EFR; |
| + } |
| + |
| + /* |
| * We distinguish between 16550A and U6 16550A by counting |
| * how many bytes are in the FIFO. |
| */ |
| @@ -2396,7 +2411,10 @@ serial8250_do_set_termios(struct uart_po |
| efr |= UART_EFR_CTS; |
| |
| serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| - serial_outp(up, UART_EFR, efr); |
| + if (up->port.flags & UPF_EXAR_EFR) |
| + serial_outp(up, UART_XR_EFR, efr); |
| + else |
| + serial_outp(up, UART_EFR, efr); |
| } |
| |
| #ifdef CONFIG_ARCH_OMAP |
| --- a/drivers/tty/serial/8250_pci.c |
| +++ b/drivers/tty/serial/8250_pci.c |
| @@ -1003,6 +1003,15 @@ static int pci_eg20t_init(struct pci_dev |
| #endif |
| } |
| |
| +static int |
| +pci_xr17c154_setup(struct serial_private *priv, |
| + const struct pciserial_board *board, |
| + struct uart_port *port, int idx) |
| +{ |
| + port->flags |= UPF_EXAR_EFR; |
| + return pci_default_setup(priv, board, port, idx); |
| +} |
| + |
| /* This should be in linux/pci_ids.h */ |
| #define PCI_VENDOR_ID_SBSMODULARIO 0x124B |
| #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B |
| @@ -1409,6 +1418,30 @@ static struct pci_serial_quirk pci_seria |
| .setup = pci_timedia_setup, |
| }, |
| /* |
| + * Exar cards |
| + */ |
| + { |
| + .vendor = PCI_VENDOR_ID_EXAR, |
| + .device = PCI_DEVICE_ID_EXAR_XR17C152, |
| + .subvendor = PCI_ANY_ID, |
| + .subdevice = PCI_ANY_ID, |
| + .setup = pci_xr17c154_setup, |
| + }, |
| + { |
| + .vendor = PCI_VENDOR_ID_EXAR, |
| + .device = PCI_DEVICE_ID_EXAR_XR17C154, |
| + .subvendor = PCI_ANY_ID, |
| + .subdevice = PCI_ANY_ID, |
| + .setup = pci_xr17c154_setup, |
| + }, |
| + { |
| + .vendor = PCI_VENDOR_ID_EXAR, |
| + .device = PCI_DEVICE_ID_EXAR_XR17C158, |
| + .subvendor = PCI_ANY_ID, |
| + .subdevice = PCI_ANY_ID, |
| + .setup = pci_xr17c154_setup, |
| + }, |
| + /* |
| * Xircom cards |
| */ |
| { |
| --- a/include/linux/serial_core.h |
| +++ b/include/linux/serial_core.h |
| @@ -46,7 +46,8 @@ |
| #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ |
| #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ |
| #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ |
| -#define PORT_MAX_8250 20 /* max port ID */ |
| +#define PORT_XR17D15X 21 /* Exar XR17D15x UART */ |
| +#define PORT_MAX_8250 21 /* max port ID */ |
| |
| /* |
| * ARM specific type numbers. These are not currently guaranteed |
| @@ -349,6 +350,7 @@ struct uart_port { |
| #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) |
| #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) |
| #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) |
| +#define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) |
| /* The exact UART type is known and should not be probed. */ |
| #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) |
| #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) |
| --- a/include/linux/serial_reg.h |
| +++ b/include/linux/serial_reg.h |
| @@ -152,6 +152,7 @@ |
| * LCR=0xBF (or DLAB=1 for 16C660) |
| */ |
| #define UART_EFR 2 /* I/O: Extended Features Register */ |
| +#define UART_XR_EFR 9 /* I/O: Extended Features Register (XR17D15x) */ |
| #define UART_EFR_CTS 0x80 /* CTS flow control */ |
| #define UART_EFR_RTS 0x40 /* RTS flow control */ |
| #define UART_EFR_SCD 0x20 /* Special character detect */ |