tty: add SPDX identifiers to all remaining files in drivers/tty/
[linux-block.git] / drivers / tty / serial / 8250 / 8250_mid.c
index ac013edf4992e74362f62ba34789f57b63ba9128..b6d326cab3ca417a94b2a3a2b72f2d559dbee3af 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * 8250_mid.c - Driver for UART on Intel Penwell and various other Intel SOCs
  *
 #define PCI_DEVICE_ID_INTEL_PNW_UART2  0x081c
 #define PCI_DEVICE_ID_INTEL_PNW_UART3  0x081d
 #define PCI_DEVICE_ID_INTEL_TNG_UART   0x1191
+#define PCI_DEVICE_ID_INTEL_CDF_UART   0x18d8
 #define PCI_DEVICE_ID_INTEL_DNV_UART   0x19d8
 
 /* Intel MID Specific registers */
-#define INTEL_MID_UART_DNV_FISR                0x08
+#define INTEL_MID_UART_FISR            0x08
 #define INTEL_MID_UART_PS              0x30
 #define INTEL_MID_UART_MUL             0x34
 #define INTEL_MID_UART_DIV             0x38
@@ -75,6 +77,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 +123,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;
 }
 
@@ -97,7 +132,7 @@ static int dnv_handle_irq(struct uart_port *p)
 {
        struct mid8250 *mid = p->private_data;
        struct uart_8250_port *up = up_to_u8250p(p);
-       unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
+       unsigned int fisr = serial_port_in(p, INTEL_MID_UART_FISR);
        u32 status;
        int ret = 0;
        int err;
@@ -131,8 +166,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 +293,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;
@@ -338,6 +379,7 @@ static const struct pci_device_id pci_ids[] = {
        MID_DEVICE(PCI_DEVICE_ID_INTEL_PNW_UART2, pnw_board),
        MID_DEVICE(PCI_DEVICE_ID_INTEL_PNW_UART3, pnw_board),
        MID_DEVICE(PCI_DEVICE_ID_INTEL_TNG_UART, tng_board),
+       MID_DEVICE(PCI_DEVICE_ID_INTEL_CDF_UART, dnv_board),
        MID_DEVICE(PCI_DEVICE_ID_INTEL_DNV_UART, dnv_board),
        { },
 };