aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250/8250_mid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/8250/8250_mid.c')
-rw-r--r--drivers/tty/serial/8250/8250_mid.c45
1 files changed, 42 insertions, 3 deletions
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;