summaryrefslogtreecommitdiffstats
path: root/sys/arm/mv/mv_pci.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2014-02-01 17:17:35 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2014-02-01 17:17:35 +0000
commitfe5ea2b0207e1ec2c4537c9b3331811e6e7c0f61 (patch)
treea83a2c1252b628ba29e227d3b9818f9a71b63d48 /sys/arm/mv/mv_pci.c
parentb6007fbe3e12e7460f4a667fe2f52a1a291dcc5c (diff)
downloadFreeBSD-src-fe5ea2b0207e1ec2c4537c9b3331811e6e7c0f61.zip
FreeBSD-src-fe5ea2b0207e1ec2c4537c9b3331811e6e7c0f61.tar.gz
Open Firmware interrupt specifiers can consist of arbitrary-length byte
strings and include arbitrary information (IRQ line/domain/sense). When the ofw_bus_map_intr() API was introduced, it assumed that, as on most systems, these were either 1 cell, containing an interrupt line, or 2, containing a line number plus a sense code. It turns out a non-negligible number of ARM systems use 3 (or even 4!) cells for interrupts, so make this more general.
Diffstat (limited to 'sys/arm/mv/mv_pci.c')
-rw-r--r--sys/arm/mv/mv_pci.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/sys/arm/mv/mv_pci.c b/sys/arm/mv/mv_pci.c
index 4660e5c..690ebb4 100644
--- a/sys/arm/mv/mv_pci.c
+++ b/sys/arm/mv/mv_pci.c
@@ -1050,7 +1050,8 @@ mv_pcib_route_interrupt(device_t bus, device_t dev, int pin)
{
struct mv_pcib_softc *sc;
struct ofw_pci_register reg;
- uint32_t pintr, mintr;
+ uint32_t pintr, mintr[4];
+ int icells;
phandle_t iparent;
sc = device_get_softc(bus);
@@ -1062,10 +1063,11 @@ mv_pcib_route_interrupt(device_t bus, device_t dev, int pin)
(pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
(pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
- if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
- sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- &iparent))
- return (ofw_bus_map_intr(dev, iparent, mintr));
+ icells = ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
+ &reg, sizeof(reg), &pintr, sizeof(pintr), mintr, sizeof(mintr),
+ &iparent);
+ if (icells > 0)
+ return (ofw_bus_map_intr(dev, iparent, icells, mintr));
/* Maybe it's a real interrupt, not an intpin */
if (pin > 4)
OpenPOWER on IntegriCloud