Skip to content

Commit

Permalink
serial: 8250_pci: Implement MSI(-X) support
Browse files Browse the repository at this point in the history
There may be setups, where legacy interrupts are not available. This is
the caese, e.g., when Linux runs as guest (aka. non-root cell) of the
partitioning hypervisor Jailhouse. There, only MSI(-X) interrupts are
available for guests.

But the 8250_pci driver currently only supports legacy ints. So let's
enable MSI(-X) interrupts.

Nevertheless, this needs to handled with care: while many 8250 devices
actually claim to support MSI(-X) interrupts it should not be enabled be
default. I had at least one device in my hands with broken MSI
implementation.

So better introduce a whitelist with devices that are known to support
MSI(-X) interrupts. I tested all devices mentioned in the patch.

Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
Link: https://lore.kernel.org/r/20190812112152.693622-1-ralf.ramsauer@oth-regensburg.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ralf Ramsauer authored and Greg Kroah-Hartman committed Sep 4, 2019
1 parent 68e26a8 commit 8428413
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion drivers/tty/serial/8250/8250_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ struct serial_private {
int line[0];
};

static const struct pci_device_id pci_use_msi[] = {
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
0xA000, 0x1000) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
0xA000, 0x1000) },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922,
0xA000, 0x1000) },
{ }
};

static int pci_default_setup(struct serial_private*,
const struct pciserial_board*, struct uart_8250_port *, int);

Expand Down Expand Up @@ -4155,7 +4165,22 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
memset(&uart, 0, sizeof(uart));
uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
uart.port.uartclk = board->base_baud * 16;
uart.port.irq = get_pci_irq(dev, board);

if (pci_match_id(pci_use_msi, dev)) {
dev_dbg(&dev->dev, "Using MSI(-X) interrupts\n");
pci_set_master(dev);
rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
} else {
dev_dbg(&dev->dev, "Using legacy interrupts\n");
rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY);
}
if (rc < 0) {
kfree(priv);
priv = ERR_PTR(rc);
goto err_deinit;
}

uart.port.irq = pci_irq_vector(dev, 0);
uart.port.dev = &dev->dev;

for (i = 0; i < nr_ports; i++) {
Expand Down

0 comments on commit 8428413

Please sign in to comment.