diff options
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r-- | drivers/tty/serial/8250/8250_dw.c | 28 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_exar.c | 487 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_gsc.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_hp300.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_lpss.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_mid.c | 45 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_moxa.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_of.c | 94 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_omap.c | 33 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 515 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_port.c | 32 | ||||
-rw-r--r-- | drivers/tty/serial/8250/Kconfig | 11 | ||||
-rw-r--r-- | drivers/tty/serial/8250/Makefile | 1 |
13 files changed, 663 insertions, 594 deletions
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index c89fafc972b6..6ee55a2d47bb 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -201,8 +201,31 @@ static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset) static int dw8250_handle_irq(struct uart_port *p) { + struct uart_8250_port *up = up_to_u8250p(p); struct dw8250_data *d = p->private_data; unsigned int iir = p->serial_in(p, UART_IIR); + unsigned int status; + unsigned long flags; + + /* + * There are ways to get Designware-based UARTs into a state where + * they are asserting UART_IIR_RX_TIMEOUT but there is no actual + * data available. If we see such a case then we'll do a bogus + * read. If we don't do this then the "RX TIMEOUT" interrupt will + * fire forever. + * + * This problem has only been observed so far when not in DMA mode + * so we limit the workaround only to non-DMA mode. + */ + if (!up->dma && ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)) { + spin_lock_irqsave(&p->lock, flags); + status = p->serial_in(p, UART_LSR); + + if (!(status & (UART_LSR_DR | UART_LSR_BI))) + (void) p->serial_in(p, UART_RX); + + spin_unlock_irqrestore(&p->lock, flags); + } if (serial8250_handle_irq(p, iir)) return 1; @@ -248,11 +271,11 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, if (!ret) p->uartclk = rate; +out: p->status &= ~UPSTAT_AUTOCTS; if (termios->c_cflag & CRTSCTS) p->status |= UPSTAT_AUTOCTS; -out: serial8250_do_set_termios(p, termios, old); } @@ -326,13 +349,11 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) p->serial_in = dw8250_serial_in32; data->uart_16550_compatible = true; } - p->set_termios = dw8250_set_termios; } /* Platforms with iDMA */ if (platform_get_resource_byname(to_platform_device(p->dev), IORESOURCE_MEM, "lpss_priv")) { - p->set_termios = dw8250_set_termios; data->dma.rx_param = p->dev->parent; data->dma.tx_param = p->dev->parent; data->dma.fn = dw8250_idma_filter; @@ -414,6 +435,7 @@ static int dw8250_probe(struct platform_device *pdev) p->serial_in = dw8250_serial_in; p->serial_out = dw8250_serial_out; p->set_ldisc = dw8250_set_ldisc; + p->set_termios = dw8250_set_termios; p->membase = devm_ioremap(dev, regs->start, resource_size(regs)); if (!p->membase) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c new file mode 100644 index 000000000000..b89c4ffc0486 --- /dev/null +++ b/drivers/tty/serial/8250/8250_exar.c @@ -0,0 +1,487 @@ +/* + * Probe module for 8250/16550-type Exar chips PCI serial ports. + * + * Based on drivers/tty/serial/8250/8250_pci.c, + * + * Copyright (C) 2017 Sudip Mukherjee, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + */ +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/serial_core.h> +#include <linux/serial_reg.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/tty.h> +#include <linux/8250_pci.h> + +#include <asm/byteorder.h> + +#include "8250.h" + +#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 +#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 +#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a +#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b +#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 +#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 +#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 +#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 +#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 + +#define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */ + +#define UART_EXAR_FCTR 0x08 /* Feature Control Register */ +#define UART_FCTR_EXAR_IRDA 0x10 /* IrDa data encode select */ +#define UART_FCTR_EXAR_485 0x20 /* Auto 485 half duplex dir ctl */ +#define UART_FCTR_EXAR_TRGA 0x00 /* FIFO trigger table A */ +#define UART_FCTR_EXAR_TRGB 0x60 /* FIFO trigger table B */ +#define UART_FCTR_EXAR_TRGC 0x80 /* FIFO trigger table C */ +#define UART_FCTR_EXAR_TRGD 0xc0 /* FIFO trigger table D programmable */ + +#define UART_EXAR_TXTRG 0x0a /* Tx FIFO trigger level write-only */ +#define UART_EXAR_RXTRG 0x0b /* Rx FIFO trigger level write-only */ + +#define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */ +#define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */ +#define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */ +#define UART_EXAR_MPIOINV_7_0 0x92 /* MPIOINV[7:0] */ +#define UART_EXAR_MPIOSEL_7_0 0x93 /* MPIOSEL[7:0] */ +#define UART_EXAR_MPIOOD_7_0 0x94 /* MPIOOD[7:0] */ +#define UART_EXAR_MPIOINT_15_8 0x95 /* MPIOINT[15:8] */ +#define UART_EXAR_MPIOLVL_15_8 0x96 /* MPIOLVL[15:8] */ +#define UART_EXAR_MPIO3T_15_8 0x97 /* MPIO3T[15:8] */ +#define UART_EXAR_MPIOINV_15_8 0x98 /* MPIOINV[15:8] */ +#define UART_EXAR_MPIOSEL_15_8 0x99 /* MPIOSEL[15:8] */ +#define UART_EXAR_MPIOOD_15_8 0x9a /* MPIOOD[15:8] */ + +struct exar8250; + +/** + * struct exar8250_board - board information + * @num_ports: number of serial ports + * @reg_shift: describes UART register mapping in PCI memory + */ +struct exar8250_board { + unsigned int num_ports; + unsigned int reg_shift; + bool has_slave; + int (*setup)(struct exar8250 *, struct pci_dev *, + struct uart_8250_port *, int); + void (*exit)(struct pci_dev *pcidev); +}; + +struct exar8250 { + unsigned int nr; + struct exar8250_board *board; + int line[0]; +}; + +static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev, + int idx, unsigned int offset, + struct uart_8250_port *port) +{ + const struct exar8250_board *board = priv->board; + unsigned int bar = 0; + + if (!pcim_iomap_table(pcidev)[bar] && !pcim_iomap(pcidev, bar, 0)) + return -ENOMEM; + + port->port.iotype = UPIO_MEM; + port->port.mapbase = pci_resource_start(pcidev, bar) + offset; + port->port.membase = pcim_iomap_table(pcidev)[bar] + offset; + port->port.regshift = board->reg_shift; + + return 0; +} + +static int +pci_fastcom335_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + unsigned int offset = idx * 0x200; + unsigned int baud = 1843200; + u8 __iomem *p; + int err; + + port->port.flags |= UPF_EXAR_EFR; + port->port.uartclk = baud * 16; + + err = default_setup(priv, pcidev, idx, offset, port); + if (err) + return err; + + p = port->port.membase; + + writeb(0x00, p + UART_EXAR_8XMODE); + writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); + writeb(32, p + UART_EXAR_TXTRG); + writeb(32, p + UART_EXAR_RXTRG); + + /* + * Setup Multipurpose Input/Output pins. + */ + if (idx == 0) { + switch (pcidev->device) { + case PCI_DEVICE_ID_COMMTECH_4222PCI335: + case PCI_DEVICE_ID_COMMTECH_4224PCI335: + writeb(0x78, p + UART_EXAR_MPIOLVL_7_0); + writeb(0x00, p + UART_EXAR_MPIOINV_7_0); + writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); + break; + case PCI_DEVICE_ID_COMMTECH_2324PCI335: + case PCI_DEVICE_ID_COMMTECH_2328PCI335: + writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); + writeb(0xc0, p + UART_EXAR_MPIOINV_7_0); + writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0); + break; + } + writeb(0x00, p + UART_EXAR_MPIOINT_7_0); + writeb(0x00, p + UART_EXAR_MPIO3T_7_0); + writeb(0x00, p + UART_EXAR_MPIOOD_7_0); + } + + return 0; +} + +static int +pci_connect_tech_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + unsigned int offset = idx * 0x200; + unsigned int baud = 1843200; + + port->port.uartclk = baud * 16; + return default_setup(priv, pcidev, idx, offset, port); +} + +static int +pci_xr17c154_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + unsigned int offset = idx * 0x200; + unsigned int baud = 921600; + + port->port.uartclk = baud * 16; + return default_setup(priv, pcidev, idx, offset, port); +} + +static void setup_gpio(u8 __iomem *p) +{ + writeb(0x00, p + UART_EXAR_MPIOINT_7_0); + writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); + writeb(0x00, p + UART_EXAR_MPIO3T_7_0); + writeb(0x00, p + UART_EXAR_MPIOINV_7_0); + writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); + writeb(0x00, p + UART_EXAR_MPIOOD_7_0); + writeb(0x00, p + UART_EXAR_MPIOINT_15_8); + writeb(0x00, p + UART_EXAR_MPIOLVL_15_8); + writeb(0x00, p + UART_EXAR_MPIO3T_15_8); + writeb(0x00, p + UART_EXAR_MPIOINV_15_8); + writeb(0x00, p + UART_EXAR_MPIOSEL_15_8); + writeb(0x00, p + UART_EXAR_MPIOOD_15_8); +} + +static void * +xr17v35x_register_gpio(struct pci_dev *pcidev) +{ + struct platform_device *pdev; + + pdev = platform_device_alloc("gpio_exar", PLATFORM_DEVID_AUTO); + if (!pdev) + return NULL; + + platform_set_drvdata(pdev, pcidev); + if (platform_device_add(pdev) < 0) { + platform_device_put(pdev); + return NULL; + } + + return pdev; +} + +static int +pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + const struct exar8250_board *board = priv->board; + unsigned int offset = idx * 0x400; + unsigned int baud = 7812500; + u8 __iomem *p; + int ret; + + port->port.uartclk = baud * 16; + /* + * Setup the uart clock for the devices on expansion slot to + * half the clock speed of the main chip (which is 125MHz) + */ + if (board->has_slave && idx >= 8) + port->port.uartclk /= 2; + + ret = default_setup(priv, pcidev, idx, offset, port); + if (ret) + return ret; + + p = port->port.membase; + + writeb(0x00, p + UART_EXAR_8XMODE); + writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); + writeb(128, p + UART_EXAR_TXTRG); + writeb(128, p + UART_EXAR_RXTRG); + + if (idx == 0) { + /* Setup Multipurpose Input/Output pins. */ + setup_gpio(p); + + port->port.private_data = xr17v35x_register_gpio(pcidev); + } + + return 0; +} + +static void pci_xr17v35x_exit(struct pci_dev *pcidev) +{ + struct exar8250 *priv = pci_get_drvdata(pcidev); + struct uart_8250_port *port = serial8250_get_port(priv->line[0]); + struct platform_device *pdev = port->port.private_data; + + platform_device_unregister(pdev); + port->port.private_data = NULL; +} + +static int +exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) +{ + unsigned int nr_ports, i, bar = 0, maxnr; + struct exar8250_board *board; + struct uart_8250_port uart; + struct exar8250 *priv; + int rc; + + board = (struct exar8250_board *)ent->driver_data; + if (!board) + return -EINVAL; + + rc = pcim_enable_device(pcidev); + if (rc) + return rc; + + maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3); + + nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f; + + priv = devm_kzalloc(&pcidev->dev, sizeof(*priv) + + sizeof(unsigned int) * nr_ports, + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->board = board; + + pci_set_master(pcidev); + + rc = pci_alloc_irq_vectors(pcidev, 1, 1, PCI_IRQ_ALL_TYPES); + if (rc < 0) + return rc; + + memset(&uart, 0, sizeof(uart)); + uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ + | UPF_EXAR_EFR; + uart.port.irq = pci_irq_vector(pcidev, 0); + uart.port.dev = &pcidev->dev; + + for (i = 0; i < nr_ports && i < maxnr; i++) { + rc = board->setup(priv, pcidev, &uart, i); + if (rc) { + dev_err(&pcidev->dev, "Failed to setup port %u\n", i); + break; + } + + dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", + uart.port.iobase, uart.port.irq, uart.port.iotype); + + priv->line[i] = serial8250_register_8250_port(&uart); + if (priv->line[i] < 0) { + dev_err(&pcidev->dev, + "Couldn't register serial port %lx, irq %d, type %d, error %d\n", + uart.port.iobase, uart.port.irq, + uart.port.iotype, priv->line[i]); + break; + } + } + priv->nr = i; + pci_set_drvdata(pcidev, priv); + return 0; +} + +static void exar_pci_remove(struct pci_dev *pcidev) +{ + struct exar8250 *priv = pci_get_drvdata(pcidev); + unsigned int i; + + for (i = 0; i < priv->nr; i++) + serial8250_unregister_port(priv->line[i]); + + if (priv->board->exit) + priv->board->exit(pcidev); +} + +static int __maybe_unused exar_suspend(struct device *dev) +{ + struct pci_dev *pcidev = to_pci_dev(dev); + struct exar8250 *priv = pci_get_drvdata(pcidev); + unsigned int i; + + for (i = 0; i < priv->nr; i++) + if (priv->line[i] >= 0) + serial8250_suspend_port(priv->line[i]); + + /* Ensure that every init quirk is properly torn down */ + if (priv->board->exit) + priv->board->exit(pcidev); + + return 0; +} + +static int __maybe_unused exar_resume(struct device *dev) +{ + struct pci_dev *pcidev = to_pci_dev(dev); + struct exar8250 *priv = pci_get_drvdata(pcidev); + unsigned int i; + + for (i = 0; i < priv->nr; i++) + if (priv->line[i] >= 0) + serial8250_resume_port(priv->line[i]); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume); + +static const struct exar8250_board pbn_fastcom335_2 = { + .num_ports = 2, + .setup = pci_fastcom335_setup, +}; + +static const struct exar8250_board pbn_fastcom335_4 = { + .num_ports = 4, + .setup = pci_fastcom335_setup, +}; + +static const struct exar8250_board pbn_fastcom335_8 = { + .num_ports = 8, + .setup = pci_fastcom335_setup, +}; + +static const struct exar8250_board pbn_connect = { + .setup = pci_connect_tech_setup, +}; + +static const struct exar8250_board pbn_exar_ibm_saturn = { + .num_ports = 1, + .setup = pci_xr17c154_setup, +}; + +static const struct exar8250_board pbn_exar_XR17C15x = { + .setup = pci_xr17c154_setup, +}; + +static const struct exar8250_board pbn_exar_XR17V35x = { + .setup = pci_xr17v35x_setup, + .exit = pci_xr17v35x_exit, +}; + +static const struct exar8250_board pbn_exar_XR17V4358 = { + .num_ports = 12, + .has_slave = true, + .setup = pci_xr17v35x_setup, + .exit = pci_xr17v35x_exit, +}; + +static const struct exar8250_board pbn_exar_XR17V8358 = { + .num_ports = 16, + .has_slave = true, + .setup = pci_xr17v35x_setup, + .exit = pci_xr17v35x_exit, +}; + +#define CONNECT_DEVICE(devid, sdevid, bd) { \ + PCI_DEVICE_SUB( \ + PCI_VENDOR_ID_EXAR, \ + PCI_DEVICE_ID_EXAR_##devid, \ + PCI_SUBVENDOR_ID_CONNECT_TECH, \ + PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_##sdevid), 0, 0, \ + (kernel_ulong_t)&bd \ + } + +#define EXAR_DEVICE(vend, devid, bd) { \ + PCI_VDEVICE(vend, PCI_DEVICE_ID_##devid), (kernel_ulong_t)&bd \ + } + +#define IBM_DEVICE(devid, sdevid, bd) { \ + PCI_DEVICE_SUB( \ + PCI_VENDOR_ID_EXAR, \ + PCI_DEVICE_ID_EXAR_##devid, \ + PCI_VENDOR_ID_IBM, \ + PCI_SUBDEVICE_ID_IBM_##sdevid), 0, 0, \ + (kernel_ulong_t)&bd \ + } + +static struct pci_device_id exar_pci_tbl[] = { + CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect), + CONNECT_DEVICE(XR17C152, UART_1_1, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_2_2, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_4_4, pbn_connect), + CONNECT_DEVICE(XR17C152, UART_2, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8, pbn_connect), + CONNECT_DEVICE(XR17C152, UART_2_485, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4_485, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8_485, pbn_connect), + + IBM_DEVICE(XR17C152, SATURN_SERIAL_ONE_PORT, pbn_exar_ibm_saturn), + + /* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */ + EXAR_DEVICE(EXAR, EXAR_XR17C152, pbn_exar_XR17C15x), + EXAR_DEVICE(EXAR, EXAR_XR17C154, pbn_exar_XR17C15x), + EXAR_DEVICE(EXAR, EXAR_XR17C158, pbn_exar_XR17C15x), + + /* Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs */ + EXAR_DEVICE(EXAR, EXAR_XR17V352, pbn_exar_XR17V35x), + EXAR_DEVICE(EXAR, EXAR_XR17V354, pbn_exar_XR17V35x), + EXAR_DEVICE(EXAR, EXAR_XR17V358, pbn_exar_XR17V35x), + EXAR_DEVICE(EXAR, EXAR_XR17V4358, pbn_exar_XR17V4358), + EXAR_DEVICE(EXAR, EXAR_XR17V8358, pbn_exar_XR17V8358), + EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x), + EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x), + EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x), + + EXAR_DEVICE(COMMTECH, COMMTECH_4222PCI335, pbn_fastcom335_2), + EXAR_DEVICE(COMMTECH, COMMTECH_4224PCI335, pbn_fastcom335_4), + EXAR_DEVICE(COMMTECH, COMMTECH_2324PCI335, pbn_fastcom335_4), + EXAR_DEVICE(COMMTECH, COMMTECH_2328PCI335, pbn_fastcom335_8), + { 0, } +}; +MODULE_DEVICE_TABLE(pci, exar_pci_tbl); + +static struct pci_driver exar_pci_driver = { + .name = "exar_serial", + .probe = exar_pci_probe, + .remove = exar_pci_remove, + .driver = { + .pm = &exar_pci_pm, + }, + .id_table = exar_pci_tbl, +}; +module_pci_driver(exar_pci_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Exar Serial Dricer"); +MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>"); diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index b1e6ae9f1ff9..63306de4390d 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c @@ -60,6 +60,10 @@ static int __init serial_init_chip(struct parisc_device *dev) 7272727 : 1843200; uart.port.mapbase = address; uart.port.membase = ioremap_nocache(address, 16); + if (!uart.port.membase) { + dev_warn(&dev->dev, "Failed to map memory\n"); + return -ENOMEM; + } uart.port.irq = dev->irq; uart.port.flags = UPF_BOOT_AUTOCONF; uart.port.dev = &dev->dev; diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index 38166db2b824..115190b7962a 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c @@ -19,7 +19,7 @@ #include "8250.h" -#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) +#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) && !defined(CONFIG_COMPILE_TEST) #warning CONFIG_SERIAL_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure? #endif diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c index 58cbb30a9401..f3ea90f0e411 100644 --- a/drivers/tty/serial/8250/8250_lpss.c +++ b/drivers/tty/serial/8250/8250_lpss.c @@ -332,10 +332,10 @@ static void lpss8250_remove(struct pci_dev *pdev) { struct lpss8250 *lpss = pci_get_drvdata(pdev); + serial8250_unregister_port(lpss->line); + if (lpss->board->exit) lpss->board->exit(lpss); - - serial8250_unregister_port(lpss->line); } static const struct lpss8250_board byt_board = { diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index ac013edf4992..ec957cce8c9a 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c @@ -75,6 +75,37 @@ static int pnw_setup(struct mid8250 *mid, struct uart_port *p) return 0; } +static int tng_handle_irq(struct uart_port *p) +{ + struct mid8250 *mid = p->private_data; + struct uart_8250_port *up = up_to_u8250p(p); + struct hsu_dma_chip *chip; + u32 status; + int ret = 0; + int err; + + chip = pci_get_drvdata(mid->dma_dev); + + /* Rx DMA */ + err = hsu_dma_get_status(chip, mid->dma_index * 2 + 1, &status); + if (err > 0) { + serial8250_rx_dma_flush(up); + ret |= 1; + } else if (err == 0) + ret |= hsu_dma_do_irq(chip, mid->dma_index * 2 + 1, status); + + /* Tx DMA */ + err = hsu_dma_get_status(chip, mid->dma_index * 2, &status); + if (err > 0) + ret |= 1; + else if (err == 0) + ret |= hsu_dma_do_irq(chip, mid->dma_index * 2, status); + + /* UART */ + ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); + return IRQ_RETVAL(ret); +} + static int tng_setup(struct mid8250 *mid, struct uart_port *p) { struct pci_dev *pdev = to_pci_dev(p->dev); @@ -90,6 +121,8 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p) mid->dma_index = index; mid->dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(5, 0)); + + p->handle_irq = tng_handle_irq; return 0; } @@ -131,8 +164,16 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) unsigned int bar = FL_GET_BASE(mid->board->flags); int ret; + pci_set_master(pdev); + + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); + if (ret < 0) + return ret; + + p->irq = pci_irq_vector(pdev, 0); + chip->dev = &pdev->dev; - chip->irq = pdev->irq; + chip->irq = pci_irq_vector(pdev, 0); chip->regs = p->membase; chip->length = pci_resource_len(pdev, bar); chip->offset = DNV_DMA_CHAN_OFFSET; @@ -250,8 +291,6 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) return ret; - pci_set_master(pdev); - mid = devm_kzalloc(&pdev->dev, sizeof(*mid), GFP_KERNEL); if (!mid) return -ENOMEM; diff --git a/drivers/tty/serial/8250/8250_moxa.c b/drivers/tty/serial/8250/8250_moxa.c index 26eb5393a263..d5069b2d4d79 100644 --- a/drivers/tty/serial/8250/8250_moxa.c +++ b/drivers/tty/serial/8250/8250_moxa.c @@ -68,6 +68,7 @@ static int moxa8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) sizeof(unsigned int) * nr_ports, GFP_KERNEL); if (!brd) return -ENOMEM; + brd->num_ports = nr_ports; memset(&uart, 0, sizeof(struct uart_8250_port)); diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index d25ab1cd4295..1cbadafc6889 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -172,7 +172,8 @@ static int of_platform_serial_probe(struct platform_device *ofdev) { const struct of_device_id *match; struct of_serial_info *info; - struct uart_port port; + struct uart_8250_port port8250; + u32 tx_threshold; int port_type; int ret; @@ -188,41 +189,24 @@ static int of_platform_serial_probe(struct platform_device *ofdev) return -ENOMEM; port_type = (unsigned long)match->data; - ret = of_platform_serial_setup(ofdev, port_type, &port, info); + memset(&port8250, 0, sizeof(port8250)); + ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info); if (ret) goto out; - switch (port_type) { - case PORT_8250 ... PORT_MAX_8250: - { - u32 tx_threshold; - struct uart_8250_port port8250; - memset(&port8250, 0, sizeof(port8250)); - port8250.port = port; + if (port8250.port.fifosize) + port8250.capabilities = UART_CAP_FIFO; - if (port.fifosize) - port8250.capabilities = UART_CAP_FIFO; + /* Check for TX FIFO threshold & set tx_loadsz */ + if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold", + &tx_threshold) == 0) && + (tx_threshold < port8250.port.fifosize)) + port8250.tx_loadsz = port8250.port.fifosize - tx_threshold; - /* Check for TX FIFO threshold & set tx_loadsz */ - if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold", - &tx_threshold) == 0) && - (tx_threshold < port.fifosize)) - port8250.tx_loadsz = port.fifosize - tx_threshold; + if (of_property_read_bool(ofdev->dev.of_node, "auto-flow-control")) + port8250.capabilities |= UART_CAP_AFE; - if (of_property_read_bool(ofdev->dev.of_node, - "auto-flow-control")) - port8250.capabilities |= UART_CAP_AFE; - - ret = serial8250_register_8250_port(&port8250); - break; - } - default: - /* need to add code for these */ - case PORT_UNKNOWN: - dev_info(&ofdev->dev, "Unknown serial port found, ignored\n"); - ret = -ENODEV; - break; - } + ret = serial8250_register_8250_port(&port8250); if (ret < 0) goto out; @@ -232,7 +216,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) return 0; out: kfree(info); - irq_dispose_mapping(port.irq); + irq_dispose_mapping(port8250.port.irq); return ret; } @@ -242,14 +226,8 @@ out: static int of_platform_serial_remove(struct platform_device *ofdev) { struct of_serial_info *info = platform_get_drvdata(ofdev); - switch (info->type) { - case PORT_8250 ... PORT_MAX_8250: - serial8250_unregister_port(info->line); - break; - default: - /* need to add code for these */ - break; - } + + serial8250_unregister_port(info->line); if (info->clk) clk_disable_unprepare(info->clk); @@ -258,18 +236,23 @@ static int of_platform_serial_remove(struct platform_device *ofdev) } #ifdef CONFIG_PM_SLEEP -static void of_serial_suspend_8250(struct of_serial_info *info) +static int of_serial_suspend(struct device *dev) { + struct of_serial_info *info = dev_get_drvdata(dev); struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; serial8250_suspend_port(info->line); + if (info->clk && (!uart_console(port) || console_suspend_enabled)) clk_disable_unprepare(info->clk); + + return 0; } -static void of_serial_resume_8250(struct of_serial_info *info) +static int of_serial_resume(struct device *dev) { + struct of_serial_info *info = dev_get_drvdata(dev); struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; @@ -277,34 +260,6 @@ static void of_serial_resume_8250(struct of_serial_info *info) clk_prepare_enable(info->clk); serial8250_resume_port(info->line); -} - -static int of_serial_suspend(struct device *dev) -{ - struct of_serial_info *info = dev_get_drvdata(dev); - - switch (info->type) { - case PORT_8250 ... PORT_MAX_8250: - of_serial_suspend_8250(info); - break; - default: - break; - } - - return 0; -} - -static int of_serial_resume(struct device *dev) -{ - struct of_serial_info *info = dev_get_drvdata(dev); - - switch (info->type) { - case PORT_8250 ... PORT_MAX_8250: - of_serial_resume_8250(info); - break; - default: - break; - } return 0; } @@ -332,6 +287,7 @@ static const struct of_device_id of_platform_serial_table[] = { .data = (void *)PORT_ALTR_16550_F128, }, { .compatible = "mrvl,mmp-uart", .data = (void *)PORT_XSCALE, }, + { .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, }, { /* end of list */ }, }; MODULE_DEVICE_TABLE(of, of_platform_serial_table); diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 61ad6c3b20a0..e7e64913a748 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -790,6 +790,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p) { struct omap8250_priv *priv = p->port.private_data; struct uart_8250_dma *dma = p->dma; + struct dma_tx_state state; unsigned long flags; int ret; @@ -800,10 +801,12 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p) return; } - ret = dmaengine_pause(dma->rxchan); - if (WARN_ON_ONCE(ret)) - priv->rx_dma_broken = true; - + ret = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); + if (ret == DMA_IN_PROGRESS) { + ret = dmaengine_pause(dma->rxchan); + if (WARN_ON_ONCE(ret)) + priv->rx_dma_broken = true; + } spin_unlock_irqrestore(&priv->rx_dma_lock, flags); __dma_rx_do_complete(p); @@ -1075,15 +1078,15 @@ static int omap8250_no_handle_irq(struct uart_port *port) } static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE; -static const u8 am4372_habit = UART_ERRATA_CLOCK_DISABLE; +static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE; static const struct of_device_id omap8250_dt_ids[] = { { .compatible = "ti,omap2-uart" }, { .compatible = "ti,omap3-uart" }, { .compatible = "ti,omap4-uart" }, { .compatible = "ti,am3352-uart", .data = &am3352_habit, }, - { .compatible = "ti,am4372-uart", .data = &am4372_habit, }, - { .compatible = "ti,dra742-uart", .data = &am4372_habit, }, + { .compatible = "ti,am4372-uart", .data = &am3352_habit, }, + { .compatible = "ti,dra742-uart", .data = &dra742_habit, }, {}, }; MODULE_DEVICE_TABLE(of, omap8250_dt_ids); @@ -1218,14 +1221,6 @@ static int omap8250_probe(struct platform_device *pdev) priv->omap8250_dma.rx_size = RX_TRIGGER; priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER; priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER; - - if (of_machine_is_compatible("ti,am33xx")) - priv->habit |= OMAP_DMA_TX_KICK; - /* - * pause is currently not supported atleast on omap-sdma - * and edma on most earlier kernels. - */ - priv->rx_dma_broken = true; } } #endif @@ -1240,7 +1235,8 @@ static int omap8250_probe(struct platform_device *pdev) pm_runtime_put_autosuspend(&pdev->dev); return 0; err: - pm_runtime_put(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; } @@ -1249,6 +1245,7 @@ static int omap8250_remove(struct platform_device *pdev) { struct omap8250_priv *priv = platform_get_drvdata(pdev); + pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); serial8250_unregister_port(priv->line); @@ -1348,6 +1345,10 @@ static int omap8250_runtime_suspend(struct device *dev) struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up; + /* In case runtime-pm tries this before we are setup */ + if (!priv) + return 0; + up = serial8250_get_port(priv->line); /* * When using 'no_console_suspend', the console UART must not be diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 116436b7fa52..00e51a064388 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1477,11 +1477,16 @@ static int pci_fintek_init(struct pci_dev *dev) { unsigned long iobase; u32 max_port, i; - u32 bar_data[3]; + resource_size_t bar_data[3]; u8 config_base; struct serial_private *priv = pci_get_drvdata(dev); struct uart_8250_port *port; + if (!(pci_resource_flags(dev, 5) & IORESOURCE_IO) || + !(pci_resource_flags(dev, 4) & IORESOURCE_IO) || + !(pci_resource_flags(dev, 3) & IORESOURCE_IO)) + return -ENODEV; + switch (dev->device) { case 0x1104: /* 4 ports */ case 0x1108: /* 8 ports */ @@ -1495,9 +1500,9 @@ static int pci_fintek_init(struct pci_dev *dev) } /* Get the io address dispatch from the BIOS */ - pci_read_config_dword(dev, 0x24, &bar_data[0]); - pci_read_config_dword(dev, 0x20, &bar_data[1]); - pci_read_config_dword(dev, 0x1c, &bar_data[2]); + bar_data[0] = pci_resource_start(dev, 5); + bar_data[1] = pci_resource_start(dev, 4); + bar_data[2] = pci_resource_start(dev, 3); for (i = 0; i < max_port; ++i) { /* UART0 configuration offset start from 0x40 */ @@ -1605,135 +1610,6 @@ static int pci_eg20t_init(struct pci_dev *dev) #endif } -#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 -#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 - -#define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */ -#define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */ -#define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */ -#define UART_EXAR_MPIOINV_7_0 0x92 /* MPIOINV[7:0] */ -#define UART_EXAR_MPIOSEL_7_0 0x93 /* MPIOSEL[7:0] */ -#define UART_EXAR_MPIOOD_7_0 0x94 /* MPIOOD[7:0] */ -#define UART_EXAR_MPIOINT_15_8 0x95 /* MPIOINT[15:8] */ -#define UART_EXAR_MPIOLVL_15_8 0x96 /* MPIOLVL[15:8] */ -#define UART_EXAR_MPIO3T_15_8 0x97 /* MPIO3T[15:8] */ -#define UART_EXAR_MPIOINV_15_8 0x98 /* MPIOINV[15:8] */ -#define UART_EXAR_MPIOSEL_15_8 0x99 /* MPIOSEL[15:8] */ -#define UART_EXAR_MPIOOD_15_8 0x9a /* MPIOOD[15:8] */ - -static int -pci_xr17c154_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_8250_port *port, int idx) -{ - port->port.flags |= UPF_EXAR_EFR; - return pci_default_setup(priv, board, port, idx); -} - -static inline int -xr17v35x_has_slave(struct serial_private *priv) -{ - const int dev_id = priv->dev->device; - - return ((dev_id == PCI_DEVICE_ID_EXAR_XR17V4358) || - (dev_id == PCI_DEVICE_ID_EXAR_XR17V8358)); -} - -static int -pci_xr17v35x_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_8250_port *port, int idx) -{ - u8 __iomem *p; - - p = pci_ioremap_bar(priv->dev, 0); - if (p == NULL) - return -ENOMEM; - - port->port.flags |= UPF_EXAR_EFR; - - /* - * Setup the uart clock for the devices on expansion slot to - * half the clock speed of the main chip (which is 125MHz) - */ - if (xr17v35x_has_slave(priv) && idx >= 8) - port->port.uartclk = (7812500 * 16 / 2); - - /* - * Setup Multipurpose Input/Output pins. - */ - if (idx == 0) { - writeb(0x00, p + UART_EXAR_MPIOINT_7_0); - writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); - writeb(0x00, p + UART_EXAR_MPIO3T_7_0); - writeb(0x00, p + UART_EXAR_MPIOINV_7_0); - writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); - writeb(0x00, p + UART_EXAR_MPIOOD_7_0); - writeb(0x00, p + UART_EXAR_MPIOINT_15_8); - writeb(0x00, p + UART_EXAR_MPIOLVL_15_8); - writeb(0x00, p + UART_EXAR_MPIO3T_15_8); - writeb(0x00, p + UART_EXAR_MPIOINV_15_8); - writeb(0x00, p + UART_EXAR_MPIOSEL_15_8); - writeb(0x00, p + UART_EXAR_MPIOOD_15_8); - } - writeb(0x00, p + UART_EXAR_8XMODE); - writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); - writeb(128, p + UART_EXAR_TXTRG); - writeb(128, p + UART_EXAR_RXTRG); - iounmap(p); - - return pci_default_setup(priv, board, port, idx); -} - -#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 -#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 -#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a -#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b - -static int -pci_fastcom335_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_8250_port *port, int idx) -{ - u8 __iomem *p; - - p = pci_ioremap_bar(priv->dev, 0); - if (p == NULL) - return -ENOMEM; - - port->port.flags |= UPF_EXAR_EFR; - - /* - * Setup Multipurpose Input/Output pins. - */ - if (idx == 0) { - switch (priv->dev->device) { - case PCI_DEVICE_ID_COMMTECH_4222PCI335: - case PCI_DEVICE_ID_COMMTECH_4224PCI335: - writeb(0x78, p + UART_EXAR_MPIOLVL_7_0); - writeb(0x00, p + UART_EXAR_MPIOINV_7_0); - writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); - break; - case PCI_DEVICE_ID_COMMTECH_2324PCI335: - case PCI_DEVICE_ID_COMMTECH_2328PCI335: - writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); - writeb(0xc0, p + UART_EXAR_MPIOINV_7_0); - writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0); - break; - } - writeb(0x00, p + UART_EXAR_MPIOINT_7_0); - writeb(0x00, p + UART_EXAR_MPIO3T_7_0); - writeb(0x00, p + UART_EXAR_MPIOOD_7_0); - } - writeb(0x00, p + UART_EXAR_8XMODE); - writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); - writeb(32, p + UART_EXAR_TXTRG); - writeb(32, p + UART_EXAR_RXTRG); - iounmap(p); - - return pci_default_setup(priv, board, port, idx); -} - static int pci_wch_ch353_setup(struct serial_private *priv, const struct pciserial_board *board, @@ -1809,9 +1685,6 @@ pci_wch_ch38x_setup(struct serial_private *priv, #define PCI_VENDOR_ID_AGESTAR 0x5372 #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 #define PCI_VENDOR_ID_ASIX 0x9710 -#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 -#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 -#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e @@ -2273,65 +2146,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .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, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V352, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V354, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V358, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V4358, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V8358, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - /* * Xircom cards */ { @@ -2556,59 +2370,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .setup = pci_asix_setup, }, /* - * Commtech, Inc. Fastcom adapters - * - */ - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4222PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4224PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_2324PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_2328PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4222PCIE, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4224PCIE, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4228PCIE, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - /* * Broadcom TruManage (NetXtreme) */ { @@ -2719,17 +2480,11 @@ enum pci_board_num_t { pbn_b0_4_1152000, - pbn_b0_2_1152000_200, - pbn_b0_4_1152000_200, - pbn_b0_8_1152000_200, + pbn_b0_4_1250000, pbn_b0_2_1843200, pbn_b0_4_1843200, - pbn_b0_2_1843200_200, - pbn_b0_4_1843200_200, - pbn_b0_8_1843200_200, - pbn_b0_1_4000000, pbn_b0_bt_1_115200, @@ -2820,15 +2575,6 @@ enum pci_board_num_t { pbn_computone_6, pbn_computone_8, pbn_sbsxrsio, - pbn_exar_XR17C152, - pbn_exar_XR17C154, - pbn_exar_XR17C158, - pbn_exar_XR17V352, - pbn_exar_XR17V354, - pbn_exar_XR17V358, - pbn_exar_XR17V4358, - pbn_exar_XR17V8358, - pbn_exar_ibm_saturn, pbn_pasemi_1682M, pbn_ni8430_2, pbn_ni8430_4, @@ -2933,25 +2679,11 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 8, }, - [pbn_b0_2_1152000_200] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 1152000, - .uart_offset = 0x200, - }, - - [pbn_b0_4_1152000_200] = { + [pbn_b0_4_1250000] = { .flags = FL_BASE0, .num_ports = 4, - .base_baud = 1152000, - .uart_offset = 0x200, - }, - - [pbn_b0_8_1152000_200] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 1152000, - .uart_offset = 0x200, + .base_baud = 1250000, + .uart_offset = 8, }, [pbn_b0_2_1843200] = { @@ -2967,24 +2699,6 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 8, }, - [pbn_b0_2_1843200_200] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 1843200, - .uart_offset = 0x200, - }, - [pbn_b0_4_1843200_200] = { - .flags = FL_BASE0, - .num_ports = 4, - .base_baud = 1843200, - .uart_offset = 0x200, - }, - [pbn_b0_8_1843200_200] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 1843200, - .uart_offset = 0x200, - }, [pbn_b0_1_4000000] = { .flags = FL_BASE0, .num_ports = 1, @@ -3469,76 +3183,6 @@ static struct pciserial_board pci_boards[] = { .reg_shift = 4, }, /* - * Exar Corp. XR17C15[248] Dual/Quad/Octal UART - * Only basic 16550A support. - * XR17C15[24] are not tested, but they should work. - */ - [pbn_exar_XR17C152] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 921600, - .uart_offset = 0x200, - }, - [pbn_exar_XR17C154] = { - .flags = FL_BASE0, - .num_ports = 4, - .base_baud = 921600, - .uart_offset = 0x200, - }, - [pbn_exar_XR17C158] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 921600, - .uart_offset = 0x200, - }, - [pbn_exar_XR17V352] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V354] = { - .flags = FL_BASE0, - .num_ports = 4, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V358] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V4358] = { - .flags = FL_BASE0, - .num_ports = 12, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V8358] = { - .flags = FL_BASE0, - .num_ports = 16, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_ibm_saturn] = { - .flags = FL_BASE0, - .num_ports = 1, - .base_baud = 921600, - .uart_offset = 0x200, - }, - - /* * PA Semi PWRficient PA6T-1682M on-chip UART */ [pbn_pasemi_1682M] = { @@ -3734,6 +3378,10 @@ static const struct pci_device_id blacklist[] = { { PCI_VDEVICE(INTEL, 0x228c), }, { PCI_VDEVICE(INTEL, 0x9ce3), }, { PCI_VDEVICE(INTEL, 0x9ce4), }, + + /* Exar devices */ + { PCI_VDEVICE(EXAR, PCI_ANY_ID), }, + { PCI_VDEVICE(COMMTECH, PCI_ANY_ID), }, }; /* @@ -3908,7 +3556,7 @@ err_out: } EXPORT_SYMBOL_GPL(pciserial_init_ports); -void pciserial_detach_ports(struct serial_private *priv) +static void pciserial_detach_ports(struct serial_private *priv) { struct pci_serial_quirk *quirk; int i; @@ -4159,58 +3807,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_VENDOR_ID_AFAVLAB, PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, pbn_b0_4_1152000 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT, - 0, 0, pbn_exar_ibm_saturn }, - { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_bt_1_115200 }, @@ -4938,45 +4534,6 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b3_8_115200 }, - - /* - * Exar Corp. XR17C15[248] Dual/Quad/Octal UART - */ - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17C152 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17C154 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17C158 }, - /* - * Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs - */ - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V352 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V354 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V358 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V4358, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V4358 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V8358, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V8358 }, /* * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART */ @@ -5552,43 +5109,15 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_wch384_4 }, - /* - * Commtech, Inc. Fastcom adapters - */ - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_2_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_4_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_4_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_8_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V352 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V354 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V358 }, - /* Fintek PCI serial cards */ { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 }, { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 }, { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 }, + /* MKS Tenta SCOM-080x serial cards */ + { PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 }, + { PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 }, + /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index c13fec451d03..6119516ef5fc 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -45,6 +45,12 @@ #include "8250.h" /* + * These are definitions for the Exar XR17V35X and XR17(C|D)15X + */ +#define UART_EXAR_SLEEP 0x8b /* Sleep mode */ +#define UART_EXAR_DVID 0x8d /* Device identification */ + +/* * Debugging. */ #if 0 @@ -273,6 +279,15 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, + [PORT_DA830] = { + .name = "TI DA8xx/66AK2x", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | + UART_FCR_R_TRIG_10, + .rxtrig_bytes = {1, 4, 8, 14}, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, }; /* Uart divisor latch read */ @@ -1753,8 +1768,6 @@ void serial8250_tx_chars(struct uart_8250_port *up) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - pr_debug("%s: THRE\n", __func__); - /* * With RPM enabled, we have to wait until the FIFO is empty before the * HW can go idle. So we get here once again with empty FIFO and disable @@ -1819,8 +1832,6 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) status = serial_port_in(port, UART_LSR); - pr_debug("%s: status = %x\n", __func__, status); - if (status & (UART_LSR_DR | UART_LSR_BI)) { if (!up->dma || handle_rx_dma(up, iir)) status = serial8250_rx_chars(up, status); @@ -2118,6 +2129,19 @@ int serial8250_do_startup(struct uart_port *port) serial_port_out(port, UART_LCR, 0); } + if (port->type == PORT_DA830) { + /* Reset the port */ + serial_port_out(port, UART_IER, 0); + serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); + mdelay(10); + + /* Enable Tx, Rx and free run mode */ + serial_port_out(port, UART_DA830_PWREMU_MGMT, + UART_DA830_PWREMU_MGMT_UTRST | + UART_DA830_PWREMU_MGMT_URRST | + UART_DA830_PWREMU_MGMT_FREE); + } + #ifdef CONFIG_SERIAL_8250_RSA /* * If this is an RSA port, see if we can kick it up to the diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 0b8b6740ba43..a65fb8197aec 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -117,7 +117,7 @@ config SERIAL_8250_DMA compatible UART controllers that support DMA signaling. config SERIAL_8250_PCI - tristate "8250/16550 PCI device support" if EXPERT + tristate "8250/16550 PCI device support" depends on SERIAL_8250 && PCI default SERIAL_8250 help @@ -127,6 +127,11 @@ config SERIAL_8250_PCI Note that serial ports on NetMos 9835 Multi-I/O cards are handled by the parport_serial driver, enabled with CONFIG_PARPORT_SERIAL. +config SERIAL_8250_EXAR + tristate "8250/16550 PCI device support" + depends on SERIAL_8250_PCI + default SERIAL_8250 + config SERIAL_8250_HP300 tristate depends on SERIAL_8250 && HP300 @@ -402,7 +407,7 @@ config SERIAL_8250_INGENIC its UARTs, say Y to this option. If unsure, say N. config SERIAL_8250_LPSS - tristate "Support for serial ports on Intel LPSS platforms" if EXPERT + tristate "Support for serial ports on Intel LPSS platforms" default SERIAL_8250 depends on SERIAL_8250 && PCI depends on X86 || COMPILE_TEST @@ -417,7 +422,7 @@ config SERIAL_8250_LPSS - Intel Quark X1000 SoC config SERIAL_8250_MID - tristate "Support for serial ports on Intel MID platforms" if EXPERT + tristate "Support for serial ports on Intel MID platforms" default SERIAL_8250 depends on SERIAL_8250 && PCI depends on X86 || COMPILE_TEST diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 850e721877a9..2f30f9ecdb1b 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o 8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o |