Merge branches 'acpi-resources', 'acpi-battery', 'acpi-doc' and 'acpi-pnp'
[linux-2.6-block.git] / drivers / tty / serial / 8250 / 8250_pci.c
index 892eb32cdef4bd98586d02e2e432c38aea512797..46bcebba54b2ff44fc32de373dfc8b09fc58687a 100644 (file)
 #include <linux/serial_core.h>
 #include <linux/8250_pci.h>
 #include <linux/bitops.h>
+#include <linux/rational.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
 
 #include <linux/dmaengine.h>
 #include <linux/platform_data/dma-dw.h>
+#include <linux/platform_data/dma-hsu.h>
 
 #include "8250.h"
 
@@ -1392,45 +1394,22 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
                struct ktermios *old)
 {
        unsigned int baud = tty_termios_baud_rate(termios);
-       unsigned int m, n;
+       unsigned long fref = 100000000, fuart = baud * 16;
+       unsigned long w = BIT(15) - 1;
+       unsigned long m, n;
        u32 reg;
 
+       /* Get Fuart closer to Fref */
+       fuart *= rounddown_pow_of_two(fref / fuart);
+
        /*
         * For baud rates 0.5M, 1M, 1.5M, 2M, 2.5M, 3M, 3.5M and 4M the
         * dividers must be adjusted.
         *
         * uartclk = (m / n) * 100 MHz, where m <= n
         */
-       switch (baud) {
-       case 500000:
-       case 1000000:
-       case 2000000:
-       case 4000000:
-               m = 64;
-               n = 100;
-               p->uartclk = 64000000;
-               break;
-       case 3500000:
-               m = 56;
-               n = 100;
-               p->uartclk = 56000000;
-               break;
-       case 1500000:
-       case 3000000:
-               m = 48;
-               n = 100;
-               p->uartclk = 48000000;
-               break;
-       case 2500000:
-               m = 40;
-               n = 100;
-               p->uartclk = 40000000;
-               break;
-       default:
-               m = 2304;
-               n = 3125;
-               p->uartclk = 73728000;
-       }
+       rational_best_approximation(fuart, fref, w, w, &m, &n);
+       p->uartclk = fuart;
 
        /* Reset the clock */
        reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT);
@@ -1525,6 +1504,167 @@ byt_serial_setup(struct serial_private *priv,
        return ret;
 }
 
+#define INTEL_MID_UART_PS              0x30
+#define INTEL_MID_UART_MUL             0x34
+#define INTEL_MID_UART_DIV             0x38
+
+static void intel_mid_set_termios(struct uart_port *p,
+                                 struct ktermios *termios,
+                                 struct ktermios *old,
+                                 unsigned long fref)
+{
+       unsigned int baud = tty_termios_baud_rate(termios);
+       unsigned short ps = 16;
+       unsigned long fuart = baud * ps;
+       unsigned long w = BIT(24) - 1;
+       unsigned long mul, div;
+
+       if (fref < fuart) {
+               /* Find prescaler value that satisfies Fuart < Fref */
+               if (fref > baud)
+                       ps = fref / baud;       /* baud rate too high */
+               else
+                       ps = 1;                 /* PLL case */
+               fuart = baud * ps;
+       } else {
+               /* Get Fuart closer to Fref */
+               fuart *= rounddown_pow_of_two(fref / fuart);
+       }
+
+       rational_best_approximation(fuart, fref, w, w, &mul, &div);
+       p->uartclk = fuart * 16 / ps;           /* core uses ps = 16 always */
+
+       writel(ps, p->membase + INTEL_MID_UART_PS);             /* set PS */
+       writel(mul, p->membase + INTEL_MID_UART_MUL);           /* set MUL */
+       writel(div, p->membase + INTEL_MID_UART_DIV);
+
+       serial8250_do_set_termios(p, termios, old);
+}
+
+static void intel_mid_set_termios_38_4M(struct uart_port *p,
+                                       struct ktermios *termios,
+                                       struct ktermios *old)
+{
+       intel_mid_set_termios(p, termios, old, 38400000);
+}
+
+static void intel_mid_set_termios_50M(struct uart_port *p,
+                                     struct ktermios *termios,
+                                     struct ktermios *old)
+{
+       /*
+        * The uart clk is 50Mhz, and the baud rate come from:
+        *      baud = 50M * MUL / (DIV * PS * DLAB)
+        */
+       intel_mid_set_termios(p, termios, old, 50000000);
+}
+
+static bool intel_mid_dma_filter(struct dma_chan *chan, void *param)
+{
+       struct hsu_dma_slave *s = param;
+
+       if (s->dma_dev != chan->device->dev || s->chan_id != chan->chan_id)
+               return false;
+
+       chan->private = s;
+       return true;
+}
+
+static int intel_mid_serial_setup(struct serial_private *priv,
+                                 const struct pciserial_board *board,
+                                 struct uart_8250_port *port, int idx,
+                                 int index, struct pci_dev *dma_dev)
+{
+       struct device *dev = port->port.dev;
+       struct uart_8250_dma *dma;
+       struct hsu_dma_slave *tx_param, *rx_param;
+
+       dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
+       if (!dma)
+               return -ENOMEM;
+
+       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;
+
+       rx_param->chan_id = index * 2 + 1;
+       tx_param->chan_id = index * 2;
+
+       dma->rxconf.src_maxburst = 64;
+       dma->txconf.dst_maxburst = 64;
+
+       rx_param->dma_dev = &dma_dev->dev;
+       tx_param->dma_dev = &dma_dev->dev;
+
+       dma->fn = intel_mid_dma_filter;
+       dma->rx_param = rx_param;
+       dma->tx_param = tx_param;
+
+       port->port.type = PORT_16750;
+       port->port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE;
+       port->dma = dma;
+
+       return pci_default_setup(priv, board, port, idx);
+}
+
+#define PCI_DEVICE_ID_INTEL_PNW_UART1  0x081b
+#define PCI_DEVICE_ID_INTEL_PNW_UART2  0x081c
+#define PCI_DEVICE_ID_INTEL_PNW_UART3  0x081d
+
+static int pnw_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 pci_dev *dma_dev;
+       int index;
+
+       switch (pdev->device) {
+       case PCI_DEVICE_ID_INTEL_PNW_UART1:
+               index = 0;
+               break;
+       case PCI_DEVICE_ID_INTEL_PNW_UART2:
+               index = 1;
+               break;
+       case PCI_DEVICE_ID_INTEL_PNW_UART3:
+               index = 2;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 3));
+
+       port->port.set_termios = intel_mid_set_termios_50M;
+
+       return intel_mid_serial_setup(priv, board, port, idx, index, dma_dev);
+}
+
+#define PCI_DEVICE_ID_INTEL_TNG_UART   0x1191
+
+static int tng_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 pci_dev *dma_dev;
+       int index = PCI_FUNC(pdev->devfn);
+
+       /* Currently no support for HSU port0 */
+       if (index-- == 0)
+               return -ENODEV;
+
+       dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(5, 0));
+
+       port->port.set_termios = intel_mid_set_termios_38_4M;
+
+       return intel_mid_serial_setup(priv, board, port, idx, index, dma_dev);
+}
+
 static int
 pci_omegapci_setup(struct serial_private *priv,
                      const struct pciserial_board *board,
@@ -1550,95 +1690,71 @@ static int pci_fintek_setup(struct serial_private *priv,
                            struct uart_8250_port *port, int idx)
 {
        struct pci_dev *pdev = priv->dev;
-       unsigned long base;
-       unsigned long iobase;
-       unsigned long ciobase = 0;
        u8 config_base;
+       u16 iobase;
+
+       config_base = 0x40 + 0x08 * idx;
+
+       /* Get the io address from configuration space */
+       pci_read_config_word(pdev, config_base + 4, &iobase);
+
+       dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%x", __func__, idx, iobase);
+
+       port->port.iotype = UPIO_PORT;
+       port->port.iobase = iobase;
+
+       return 0;
+}
+
+static int pci_fintek_init(struct pci_dev *dev)
+{
+       unsigned long iobase;
+       u32 max_port, i;
        u32 bar_data[3];
+       u8 config_base;
 
-       /*
-        * Find each UARTs offset in PCI configuraion space
-        */
-       switch (idx) {
-       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;
+       switch (dev->device) {
+       case 0x1104: /* 4 ports */
+       case 0x1108: /* 8 ports */
+               max_port = dev->device & 0xff;
                break;
-       case 9:
-               config_base = 0x88;
-               break;
-       case 10:
-               config_base = 0x90;
-               break;
-       case 11:
-               config_base = 0x98;
+       case 0x1112: /* 12 ports */
+               max_port = 12;
                break;
        default:
-               /* Unknown number of ports, get out of here */
                return -EINVAL;
        }
 
-       if (idx < 4) {
-               base = pci_resource_start(priv->dev, 3);
-               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;
+       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]);
 
-       dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n",
-               __func__, idx, iobase, ciobase, config_base);
+       for (i = 0; i < max_port; ++i) {
+               /* UART0 configuration offset start from 0x40 */
+               config_base = 0x40 + 0x08 * i;
 
-       /* Enable UART I/O port */
-       pci_write_config_byte(pdev, config_base + 0x00, 0x01);
+               /* Calculate Real IO Port */
+               iobase = (bar_data[i / 4] & 0xffffffe0) + (i % 4) * 8;
 
-       /* Select 128-byte FIFO and 8x FIFO threshold */
-       pci_write_config_byte(pdev, config_base + 0x01, 0x33);
+               /* Enable UART I/O port */
+               pci_write_config_byte(dev, config_base + 0x00, 0x01);
 
-       /* LSB UART */
-       pci_write_config_byte(pdev, config_base + 0x04, (u8)(iobase & 0xff));
+               /* Select 128-byte FIFO and 8x FIFO threshold */
+               pci_write_config_byte(dev, config_base + 0x01, 0x33);
 
-       /* MSB UART */
-       pci_write_config_byte(pdev, config_base + 0x05, (u8)((iobase & 0xff00) >> 8));
+               /* LSB UART */
+               pci_write_config_byte(dev, config_base + 0x04,
+                               (u8)(iobase & 0xff));
 
-       /* irq number, this usually fails, but the spec says to do it anyway. */
-       pci_write_config_byte(pdev, config_base + 0x06, pdev->irq);
+               /* MSB UART */
+               pci_write_config_byte(dev, config_base + 0x05,
+                               (u8)((iobase & 0xff00) >> 8));
 
-       port->port.iotype = UPIO_PORT;
-       port->port.iobase = iobase;
-       port->port.mapbase = 0;
-       port->port.membase = NULL;
-       port->port.regshift = 0;
+               pci_write_config_byte(dev, config_base + 0x06, dev->irq);
+       }
 
-       return 0;
+       return max_port;
 }
 
 static int skip_tx_en_setup(struct serial_private *priv,
@@ -1882,6 +1998,8 @@ pci_wch_ch38x_setup(struct serial_private *priv,
 #define PCIE_DEVICE_ID_WCH_CH382_2S1P  0x3250
 #define PCIE_DEVICE_ID_WCH_CH384_4S    0x3470
 
+#define PCI_DEVICE_ID_EXAR_XR17V8358   0x8358
+
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584        0x1584
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588        0x1588
@@ -1987,6 +2105,34 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = byt_serial_setup,
        },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_PNW_UART1,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pnw_serial_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_PNW_UART2,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pnw_serial_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_PNW_UART3,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pnw_serial_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_TNG_UART,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = tng_serial_setup,
+       },
        {
                .vendor         = PCI_VENDOR_ID_INTEL,
                .device         = PCI_DEVICE_ID_INTEL_BSW_UART1,
@@ -2376,6 +2522,13 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .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
         */
@@ -2653,6 +2806,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_fintek_setup,
+               .init           = pci_fintek_init,
        },
        {
                .vendor         = 0x1c29,
@@ -2660,6 +2814,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_fintek_setup,
+               .init           = pci_fintek_init,
        },
        {
                .vendor         = 0x1c29,
@@ -2667,6 +2822,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_fintek_setup,
+               .init           = pci_fintek_init,
        },
 
        /*
@@ -2852,6 +3008,7 @@ enum pci_board_num_t {
        pbn_exar_XR17V352,
        pbn_exar_XR17V354,
        pbn_exar_XR17V358,
+       pbn_exar_XR17V8358,
        pbn_exar_ibm_saturn,
        pbn_pasemi_1682M,
        pbn_ni8430_2,
@@ -2864,6 +3021,8 @@ enum pci_board_num_t {
        pbn_ADDIDATA_PCIe_8_3906250,
        pbn_ce4100_1_115200,
        pbn_byt,
+       pbn_pnw,
+       pbn_tng,
        pbn_qrk,
        pbn_omegapci,
        pbn_NETMOS9900_2s_115200,
@@ -3536,6 +3695,14 @@ static struct pciserial_board pci_boards[] = {
                .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,
@@ -3630,6 +3797,16 @@ static struct pciserial_board pci_boards[] = {
                .uart_offset    = 0x80,
                .reg_shift      = 2,
        },
+       [pbn_pnw] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 115200,
+       },
+       [pbn_tng] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 1843200,
+       },
        [pbn_qrk] = {
                .flags          = FL_BASE0,
                .num_ports      = 1,
@@ -4006,41 +4183,41 @@ static void pciserial_remove_one(struct pci_dev *dev)
        pci_disable_device(dev);
 }
 
-#ifdef CONFIG_PM
-static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pciserial_suspend_one(struct device *dev)
 {
-       struct serial_private *priv = pci_get_drvdata(dev);
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct serial_private *priv = pci_get_drvdata(pdev);
 
        if (priv)
                pciserial_suspend_ports(priv);
 
-       pci_save_state(dev);
-       pci_set_power_state(dev, pci_choose_state(dev, state));
        return 0;
 }
 
-static int pciserial_resume_one(struct pci_dev *dev)
+static int pciserial_resume_one(struct device *dev)
 {
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct serial_private *priv = pci_get_drvdata(pdev);
        int err;
-       struct serial_private *priv = pci_get_drvdata(dev);
-
-       pci_set_power_state(dev, PCI_D0);
-       pci_restore_state(dev);
 
        if (priv) {
                /*
                 * The device may have been disabled.  Re-enable it.
                 */
-               err = pci_enable_device(dev);
+               err = pci_enable_device(pdev);
                /* FIXME: We cannot simply error out here */
                if (err)
-                       dev_err(&dev->dev, "Unable to re-enable ports, trying to continue.\n");
+                       dev_err(dev, "Unable to re-enable ports, trying to continue.\n");
                pciserial_resume_ports(priv);
        }
        return 0;
 }
 #endif
 
+static SIMPLE_DEV_PM_OPS(pciserial_pm_ops, pciserial_suspend_one,
+                        pciserial_resume_one);
+
 static struct pci_device_id serial_pci_tbl[] = {
        /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
        {       PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
@@ -4921,7 +5098,7 @@ static struct pci_device_id serial_pci_tbl[] = {
                0,
                0, pbn_exar_XR17C158 },
        /*
-        * Exar Corp. XR17V35[248] Dual/Quad/Octal PCIe UARTs
+        * 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,
@@ -4935,7 +5112,10 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_ANY_ID, PCI_ANY_ID,
                0,
                0, pbn_exar_XR17V358 },
-
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V8358,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0,
+               0, pbn_exar_XR17V8358 },
        /*
         * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
         */
@@ -5362,6 +5542,26 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
                pbn_byt },
 
+       /*
+        * Intel Penwell
+        */
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PNW_UART1,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_pnw},
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PNW_UART2,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_pnw},
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PNW_UART3,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_pnw},
+
+       /*
+        * Intel Tangier
+        */
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TNG_UART,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_tng},
+
        /*
         * Intel Quark x1000
         */
@@ -5510,10 +5710,9 @@ static struct pci_driver serial_pci_driver = {
        .name           = "serial",
        .probe          = pciserial_init_one,
        .remove         = pciserial_remove_one,
-#ifdef CONFIG_PM
-       .suspend        = pciserial_suspend_one,
-       .resume         = pciserial_resume_one,
-#endif
+       .driver         = {
+               .pm     = &pciserial_pm_ops,
+       },
        .id_table       = serial_pci_tbl,
        .err_handler    = &serial8250_err_handler,
 };