svn commit: r311987 - head/sys/dev/uart
Bruce M Simpson
bms at FreeBSD.org
Thu Jan 12 16:30:28 UTC 2017
Author: bms
Date: Thu Jan 12 16:30:27 2017
New Revision: 311987
URL: https://svnweb.freebsd.org/changeset/base/311987
Log:
Allow uart(4) to use MSI interrupts on single-port PCI instances.
Do this here as puc(4) disallows single-port instances; at least
one multi-port PCIe UART chip (in this case, the ASIX MCS9922)
present separate PCI configuration space (functions) for each UART.
Tested using lrzsz and a null-modem cable. The ExpressCard/34
variants containing the MCS9922 should also use MSI with this change.
Reviewed by: jhb, imp, rpokala
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D9123
Modified:
head/sys/dev/uart/uart_bus_pci.c
head/sys/dev/uart/uart_core.c
Modified: head/sys/dev/uart/uart_bus_pci.c
==============================================================================
--- head/sys/dev/uart/uart_bus_pci.c Thu Jan 12 16:24:10 2017 (r311986)
+++ head/sys/dev/uart/uart_bus_pci.c Thu Jan 12 16:30:27 2017 (r311987)
@@ -45,12 +45,14 @@ __FBSDID("$FreeBSD$");
#define DEFAULT_RCLK 1843200
static int uart_pci_probe(device_t dev);
+static int uart_pci_attach(device_t dev);
+static int uart_pci_detach(device_t dev);
static device_method_t uart_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uart_pci_probe),
- DEVMETHOD(device_attach, uart_bus_attach),
- DEVMETHOD(device_detach, uart_bus_detach),
+ DEVMETHOD(device_attach, uart_pci_attach),
+ DEVMETHOD(device_detach, uart_pci_detach),
DEVMETHOD(device_resume, uart_bus_resume),
DEVMETHOD_END
};
@@ -209,4 +211,40 @@ uart_pci_probe(device_t dev)
return (result);
}
+static int
+uart_pci_attach(device_t dev)
+{
+ struct uart_softc *sc;
+ int count;
+
+ sc = device_get_softc(dev);
+
+ /*
+ * Use MSI in preference to legacy IRQ if available.
+ * Whilst some PCIe UARTs support >1 MSI vector, use only the first.
+ */
+ if (pci_msi_count(dev) > 0) {
+ count = 1;
+ if (pci_alloc_msi(dev, &count) == 0) {
+ sc->sc_irid = 1;
+ device_printf(dev, "Using %d MSI message\n", count);
+ }
+ }
+
+ return (uart_bus_attach(dev));
+}
+
+static int
+uart_pci_detach(device_t dev)
+{
+ struct uart_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->sc_irid != 0)
+ pci_release_msi(dev);
+
+ return (uart_bus_detach(dev));
+}
+
DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL);
Modified: head/sys/dev/uart/uart_core.c
==============================================================================
--- head/sys/dev/uart/uart_core.c Thu Jan 12 16:24:10 2017 (r311986)
+++ head/sys/dev/uart/uart_core.c Thu Jan 12 16:30:27 2017 (r311987)
@@ -677,7 +677,6 @@ uart_bus_attach(device_t dev)
* safest thing to do.
*/
if (filt != FILTER_SCHEDULE_THREAD && !uart_force_poll) {
- sc->sc_irid = 0;
sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
}
More information about the svn-src-all
mailing list