Configure interrupt sense based on device tree information. This extends

the OF interrupt map API to return sense information to the caller and
the PowerPC Open Firmware PCI base driver to use it to program the PIC.
This commit is contained in:
Nathan Whitehorn 2013-12-17 14:50:35 +00:00
parent e7a9eed7a8
commit cb6d9d6cb1
2 changed files with 14 additions and 14 deletions

View File

@ -285,7 +285,7 @@ ofw_bus_lookup_imap(phandle_t node, struct ofw_bus_iinfo *ii, void *reg,
* maskbuf must point to a buffer of length physsz + intrsz.
* The interrupt is returned in result, which must point to a buffer of length
* rintrsz (which gives the expected size of the mapped interrupt).
* Returns 1 if a mapping was found, 0 otherwise.
* Returns number of cells in the interrupt if a mapping was found, 0 otherwise.
*/
int
ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
@ -325,19 +325,13 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
tsz = physsz + intrsz + sizeof(phandle_t) + pintrsz;
KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map"));
/*
* XXX: Apple hardware uses a second cell to set information
* on the interrupt trigger type. This information should
* be used somewhere to program the PIC.
*/
if (bcmp(ref, mptr, physsz + intrsz) == 0) {
bcopy(mptr + physsz + intrsz + sizeof(parent),
result, rintrsz);
result, MIN(rintrsz, pintrsz));
if (iparent != NULL)
*iparent = parent;
return (1);
return (pintrsz/sizeof(pcell_t));
}
mptr += tsz;
i -= tsz;

View File

@ -256,7 +256,8 @@ ofw_pci_route_interrupt(device_t bus, device_t dev, int pin)
{
struct ofw_pci_softc *sc;
struct ofw_pci_register reg;
uint32_t pintr, mintr;
uint32_t pintr, mintr[2];
int intrcells;
phandle_t iparent;
uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
@ -269,10 +270,15 @@ ofw_pci_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, maskbuf))
return (ofw_bus_map_intr(dev, iparent, mintr));
intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev),
&sc->sc_pci_iinfo, &reg, sizeof(reg), &pintr, sizeof(pintr),
mintr, sizeof(mintr), &iparent, maskbuf);
if (intrcells) {
pintr = ofw_bus_map_intr(dev, iparent, mintr[0]);
if (intrcells == 2)
ofw_bus_config_intr(dev, pintr, mintr[1]);
return (pintr);
}
/* Maybe it's a real interrupt, not an intpin */
if (pin > 4)