X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=drivers%2Ftty%2Fserial%2F8250%2F8250_pci.c;h=31feeb2d0a6688513e1dccf82521f281d9842b03;hb=cb8ee9f08c4abfd8744eabffc467c06795c835d9;hp=4f1cd296f1b13bb4a56d55f5b5e96d76a2a0b6fe;hpb=8a5de18239e418fe7b1f36504834689f754d8ccc;p=cascardo%2Flinux.git diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 4f1cd296f1b1..31feeb2d0a66 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -25,6 +25,9 @@ #include #include +#include +#include + #include "8250.h" /* @@ -76,29 +79,24 @@ setup_port(struct serial_private *priv, struct uart_8250_port *port, int bar, int offset, int regshift) { struct pci_dev *dev = priv->dev; - unsigned long base, len; if (bar >= PCI_NUM_BAR_RESOURCES) return -EINVAL; - base = pci_resource_start(dev, bar); - if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { - len = pci_resource_len(dev, bar); - if (!priv->remapped_bar[bar]) - priv->remapped_bar[bar] = ioremap_nocache(base, len); + priv->remapped_bar[bar] = pci_ioremap_bar(dev, bar); if (!priv->remapped_bar[bar]) return -ENOMEM; port->port.iotype = UPIO_MEM; port->port.iobase = 0; - port->port.mapbase = base + offset; + port->port.mapbase = pci_resource_start(dev, bar) + offset; port->port.membase = priv->remapped_bar[bar] + offset; port->port.regshift = regshift; } else { port->port.iotype = UPIO_PORT; - port->port.iobase = base + offset; + port->port.iobase = pci_resource_start(dev, bar) + offset; port->port.mapbase = 0; port->port.membase = NULL; port->port.regshift = 0; @@ -314,7 +312,6 @@ static void pci_plx9050_exit(struct pci_dev *dev) static void pci_ni8420_exit(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; unsigned int bar = 0; if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { @@ -322,9 +319,7 @@ static void pci_ni8420_exit(struct pci_dev *dev) return; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return; @@ -346,7 +341,6 @@ static void pci_ni8420_exit(struct pci_dev *dev) static void pci_ni8430_exit(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; unsigned int bar = 0; if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { @@ -354,9 +348,7 @@ static void pci_ni8430_exit(struct pci_dev *dev) return; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return; @@ -679,7 +671,6 @@ static int pci_xircom_init(struct pci_dev *dev) static int pci_ni8420_init(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; unsigned int bar = 0; if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { @@ -687,9 +678,7 @@ static int pci_ni8420_init(struct pci_dev *dev) return 0; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return -ENOMEM; @@ -711,7 +700,7 @@ static int pci_ni8420_init(struct pci_dev *dev) static int pci_ni8430_init(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; + struct pci_bus_region region; u32 device_window; unsigned int bar = 0; @@ -720,14 +709,17 @@ static int pci_ni8430_init(struct pci_dev *dev) return 0; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return -ENOMEM; - /* Set device window address and size in BAR0 */ - device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) + /* + * Set device window address and size in BAR0, while acknowledging that + * the resource structure may contain a translated address that differs + * from the address the device responds to. + */ + pcibios_resource_to_bus(dev->bus, ®ion, &dev->resource[bar]); + device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE; writel(device_window, p + MITE_IOWBSR1); @@ -754,8 +746,8 @@ pci_ni8430_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *port, int idx) { + struct pci_dev *dev = priv->dev; void __iomem *p; - unsigned long base, len; unsigned int bar, offset = board->first_offset; if (idx >= board->num_ports) @@ -764,9 +756,9 @@ pci_ni8430_setup(struct serial_private *priv, bar = FL_GET_BASE(board->flags); offset += idx * board->uart_offset; - base = pci_resource_start(priv->dev, bar); - len = pci_resource_len(priv->dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); + if (!p) + return -ENOMEM; /* enable the transceiver */ writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE, @@ -999,6 +991,40 @@ static void pci_ite887x_exit(struct pci_dev *dev) release_region(ioport, ITE_887x_IOSIZE); } +/* + * EndRun Technologies. + * Determine the number of ports available on the device. + */ +#define PCI_VENDOR_ID_ENDRUN 0x7401 +#define PCI_DEVICE_ID_ENDRUN_1588 0xe100 + +static int pci_endrun_init(struct pci_dev *dev) +{ + u8 __iomem *p; + unsigned long deviceID; + unsigned int number_uarts = 0; + + /* EndRun device is all 0xexxx */ + if (dev->vendor == PCI_VENDOR_ID_ENDRUN && + (dev->device & 0xf000) != 0xe000) + return 0; + + p = pci_iomap(dev, 0, 5); + if (p == NULL) + return -ENOMEM; + + deviceID = ioread32(p); + /* EndRun device */ + if (deviceID == 0x07000200) { + number_uarts = ioread8(p + 4); + dev_dbg(&dev->dev, + "%d ports detected on EndRun PCI Express device\n", + number_uarts); + } + pci_iounmap(dev, p); + return number_uarts; +} + /* * Oxford Semiconductor Inc. * Check that device is part of the Tornado range of devices, then determine @@ -1349,6 +1375,9 @@ ce4100_serial_setup(struct serial_private *priv, #define PCI_DEVICE_ID_INTEL_BYT_UART1 0x0f0a #define PCI_DEVICE_ID_INTEL_BYT_UART2 0x0f0c +#define PCI_DEVICE_ID_INTEL_BSW_UART1 0x228a +#define PCI_DEVICE_ID_INTEL_BSW_UART2 0x228c + #define BYT_PRV_CLK 0x800 #define BYT_PRV_CLK_EN (1 << 0) #define BYT_PRV_CLK_M_VAL_SHIFT 1 @@ -1414,7 +1443,13 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios, static bool byt_dma_filter(struct dma_chan *chan, void *param) { - return chan->chan_id == *(int *)param; + struct dw_dma_slave *dws = param; + + if (dws->dma_dev != chan->device->dev) + return false; + + chan->private = dws; + return true; } static int @@ -1422,35 +1457,57 @@ byt_serial_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *port, int idx) { + struct pci_dev *pdev = priv->dev; + struct device *dev = port->port.dev; struct uart_8250_dma *dma; + struct dw_dma_slave *tx_param, *rx_param; + struct pci_dev *dma_dev; int ret; - dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL); + dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); if (!dma) return -ENOMEM; - switch (priv->dev->device) { + tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL); + if (!tx_param) + return -ENOMEM; + + rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL); + if (!rx_param) + return -ENOMEM; + + switch (pdev->device) { case PCI_DEVICE_ID_INTEL_BYT_UART1: - dma->rx_chan_id = 3; - dma->tx_chan_id = 2; + case PCI_DEVICE_ID_INTEL_BSW_UART1: + rx_param->src_id = 3; + tx_param->dst_id = 2; break; case PCI_DEVICE_ID_INTEL_BYT_UART2: - dma->rx_chan_id = 5; - dma->tx_chan_id = 4; + case PCI_DEVICE_ID_INTEL_BSW_UART2: + rx_param->src_id = 5; + tx_param->dst_id = 4; break; default: return -EINVAL; } - dma->rxconf.slave_id = dma->rx_chan_id; + rx_param->src_master = 1; + rx_param->dst_master = 0; + dma->rxconf.src_maxburst = 16; - dma->txconf.slave_id = dma->tx_chan_id; + tx_param->src_master = 1; + tx_param->dst_master = 0; + dma->txconf.dst_maxburst = 16; + dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); + rx_param->dma_dev = &dma_dev->dev; + tx_param->dma_dev = &dma_dev->dev; + dma->fn = byt_dma_filter; - dma->rx_param = &dma->rx_chan_id; - dma->tx_param = &dma->tx_chan_id; + dma->rx_param = rx_param; + dma->tx_param = tx_param; ret = pci_default_setup(priv, board, port, idx); port->port.iotype = UPIO_MEM; @@ -1497,25 +1554,48 @@ static int pci_fintek_setup(struct serial_private *priv, unsigned long iobase; unsigned long ciobase = 0; u8 config_base; + u32 bar_data[3]; /* - * We are supposed to be able to read these from the PCI config space, - * but the values there don't seem to match what we need to use, so - * just use these hard-coded values for now, as they are correct. + * Find each UARTs offset in PCI configuraion space */ switch (idx) { - case 0: iobase = 0xe000; config_base = 0x40; break; - case 1: iobase = 0xe008; config_base = 0x48; break; - case 2: iobase = 0xe010; config_base = 0x50; break; - case 3: iobase = 0xe018; config_base = 0x58; break; - case 4: iobase = 0xe020; config_base = 0x60; break; - case 5: iobase = 0xe028; config_base = 0x68; break; - case 6: iobase = 0xe030; config_base = 0x70; break; - case 7: iobase = 0xe038; config_base = 0x78; break; - case 8: iobase = 0xe040; config_base = 0x80; break; - case 9: iobase = 0xe048; config_base = 0x88; break; - case 10: iobase = 0xe050; config_base = 0x90; break; - case 11: iobase = 0xe058; config_base = 0x98; break; + case 0: + config_base = 0x40; + break; + case 1: + config_base = 0x48; + break; + case 2: + config_base = 0x50; + break; + case 3: + config_base = 0x58; + break; + case 4: + config_base = 0x60; + break; + case 5: + config_base = 0x68; + break; + case 6: + config_base = 0x70; + break; + case 7: + config_base = 0x78; + break; + case 8: + config_base = 0x80; + break; + case 9: + config_base = 0x88; + break; + case 10: + config_base = 0x90; + break; + case 11: + config_base = 0x98; + break; default: /* Unknown number of ports, get out of here */ return -EINVAL; @@ -1526,6 +1606,14 @@ static int pci_fintek_setup(struct serial_private *priv, ciobase = (int)(base + (0x8 * idx)); } + /* Get the io address dispatch from the BIOS */ + pci_read_config_dword(pdev, 0x24, &bar_data[0]); + pci_read_config_dword(pdev, 0x20, &bar_data[1]); + pci_read_config_dword(pdev, 0x1c, &bar_data[2]); + + /* Calculate Real IO Port */ + iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8; + dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n", __func__, idx, iobase, ciobase, config_base); @@ -1726,6 +1814,16 @@ pci_wch_ch353_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +static int +pci_wch_ch382_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_8250_port *port, int idx) +{ + port->port.flags |= UPF_FIXED_TYPE; + port->port.type = PORT_16850; + return pci_default_setup(priv, board, port, idx); +} + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1780,6 +1878,8 @@ pci_wch_ch353_setup(struct serial_private *priv, #define PCI_VENDOR_ID_SUNIX 0x1fd4 #define PCI_DEVICE_ID_SUNIX_1999 0x1999 +#define PCIE_VENDOR_ID_WCH 0x1c00 +#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -1893,6 +1993,20 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_default_setup, }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_BSW_UART1, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = byt_serial_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_BSW_UART2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = byt_serial_setup, + }, /* * ITE */ @@ -2297,6 +2411,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .init = pci_netmos_init, .setup = pci_netmos_9900_setup, }, + /* + * EndRun Technologies + */ + { + .vendor = PCI_VENDOR_ID_ENDRUN, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_endrun_init, + .setup = pci_default_setup, + }, /* * For Oxford Semiconductor Tornado based devices */ @@ -2446,6 +2571,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_wch_ch353_setup, }, + /* WCH CH382 2S1P card (16750 clone) */ + { + .vendor = PCIE_VENDOR_ID_WCH, + .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pci_wch_ch382_setup, + }, /* * ASIX devices with FIFO bug */ @@ -2706,6 +2839,7 @@ enum pci_board_num_t { pbn_panacom2, pbn_panacom4, pbn_plx_romulus, + pbn_endrun_2_4000000, pbn_oxsemi, pbn_oxsemi_1_4000000, pbn_oxsemi_2_4000000, @@ -3250,6 +3384,20 @@ static struct pciserial_board pci_boards[] = { .first_offset = 0x03, }, + /* + * EndRun Technologies + * Uses the size of PCI Base region 0 to + * signal now many ports are available + * 2 port 952 Uart support + */ + [pbn_endrun_2_4000000] = { + .flags = FL_BASE0, + .num_ports = 2, + .base_baud = 4000000, + .uart_offset = 0x200, + .first_offset = 0x1000, + }, + /* * This board uses the size of PCI Base region 0 to * signal now many ports are available @@ -3538,6 +3686,7 @@ static const struct pci_device_id blacklist[] = { /* multi-io cards handled by parport_serial */ { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ + { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ }; /* @@ -4122,6 +4271,13 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, 0x10b5, 0x106a, 0, 0, pbn_plx_romulus }, + /* + * EndRun Technologies. PCI express device range. + * EndRun PTP/1588 has 2 Native UARTs. + */ + { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_endrun_2_4000000 }, /* * Quatech cards. These actually have configurable clocks but for * now we just use the default. @@ -5192,6 +5348,14 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, pbn_byt }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART1, + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, + pbn_byt }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART2, + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, + pbn_byt }, /* * Intel Quark x1000