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:
parent
e7a9eed7a8
commit
cb6d9d6cb1
@ -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;
|
||||
|
@ -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, ®,
|
||||
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, ®, 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)
|
||||
|
Loading…
Reference in New Issue
Block a user