Date: Fri, 14 Nov 2008 04:48:14 GMT From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 152961 for review Message-ID: <200811140448.mAE4mETa072066@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=152961 Change 152961 by nwhitehorn@nwhitehorn_trantor on 2008/11/14 04:47:43 Make the unified OFW PCI stuff really work well. IRQs show up in dmesg, and interrupt assignment works on Uninorth systems with many PCI devices, which it did not before. Once sparc64 can use this code too (which requires only mechanical changes, since it came from sparc64), it will be in good shape to merge. Affected files ... .. //depot/projects/ppc-g5/sys/powerpc/ofw/ofw_pcibus.c#3 edit .. //depot/projects/ppc-g5/sys/powerpc/powermac/cpcht.c#9 edit .. //depot/projects/ppc-g5/sys/powerpc/powermac/cpchtvar.h#3 edit .. //depot/projects/ppc-g5/sys/powerpc/powermac/grackle.c#6 edit .. //depot/projects/ppc-g5/sys/powerpc/powermac/gracklevar.h#3 edit .. //depot/projects/ppc-g5/sys/powerpc/powermac/uninorth.c#7 edit .. //depot/projects/ppc-g5/sys/powerpc/powermac/uninorthvar.h#6 edit Differences ... ==== //depot/projects/ppc-g5/sys/powerpc/ofw/ofw_pcibus.c#3 (text+ko) ==== @@ -56,8 +56,8 @@ typedef uint32_t ofw_pci_intr_t; /* Helper functions */ -static void ofw_pcibus_setup_device(device_t bridge, uint32_t clock, - u_int busno, u_int slot, u_int func); +static void ofw_pcibus_setup_device(device_t bridge, phandle_t dev, + uint32_t clock, u_int busno, u_int slot, u_int func); /* Methods */ static device_probe_t ofw_pcibus_probe; @@ -114,16 +114,20 @@ * Perform miscellaneous setups the firmware usually does not do for us. */ static void -ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno, - u_int slot, u_int func) +ofw_pcibus_setup_device(device_t bridge, phandle_t dev, uint32_t clock, + u_int busno, u_int slot, u_int func) { + int intline = PCI_INVALID_IRQ; + /* * The preset in the intline register is usually wrong. Reset * it to 255, so that the PCI code will reroute the interrupt if * needed. */ + if (OF_getproplen(dev, "interrupts") > 0) + intline = 0; PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_INTLINE, - PCI_INVALID_IRQ, 1); + intline, 1); } static int @@ -155,7 +159,7 @@ /* Some OFW device trees contain dupes. */ if (pci_find_dbsf(domain, busno, slot, func) != NULL) continue; - ofw_pcibus_setup_device(pcib, clock, busno, slot, func); + ofw_pcibus_setup_device(pcib, child, clock, busno, slot, func); dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, domain, busno, slot, func, sizeof(*dinfo)); if (dinfo == NULL) ==== //depot/projects/ppc-g5/sys/powerpc/powermac/cpcht.c#9 (text+ko) ==== @@ -318,7 +318,7 @@ cpcpci_attach(device_t dev) { struct cpcpci_softc *sc; - phandle_t node; + phandle_t node, iparent; u_int32_t reg[2], busrange[2], config_base; struct cpcpci_range *rp, *io, *mem[2]; struct cpcpci_range fakeio; @@ -415,6 +415,12 @@ ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t)); + /* We need the number of interrupt cells to read the imap */ + sc->sc_icells = 2; + if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) > 0) + OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells, + sizeof(sc->sc_icells)); + device_add_child(dev, "pci", device_get_unit(dev)); return (bus_generic_attach(dev)); @@ -606,14 +612,15 @@ { struct cpcpci_softc *sc; struct ofw_pci_register reg; - uint32_t pintr, mintr; + uint32_t pintr, mintr[2]; uint8_t maskbuf[sizeof(reg) + sizeof(pintr)]; sc = device_get_softc(bus); pintr = pin; if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, ®, - sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf)) - return (mintr); + sizeof(reg), &pintr, sizeof(pintr), &mintr, + sizeof(mintr[0])*sc->sc_icells, maskbuf)) + return (mintr[0]); /* Maybe it's a real interrupt, not an intpin */ if (pin > 4) ==== //depot/projects/ppc-g5/sys/powerpc/powermac/cpchtvar.h#3 (text+ko) ==== @@ -53,6 +53,7 @@ bus_space_tag_t sc_memt; bus_dma_tag_t sc_dmat; struct ofw_bus_iinfo sc_pci_iinfo; + int sc_icells; }; #endif /* _POWERPC_POWERMAC_CPCHTVAR_H_ */ ==== //depot/projects/ppc-g5/sys/powerpc/powermac/grackle.c#6 (text+ko) ==== @@ -165,7 +165,7 @@ grackle_attach(device_t dev) { struct grackle_softc *sc; - phandle_t node; + phandle_t node, iparent; u_int32_t busrange[2]; struct grackle_range *rp, *io, *mem[2]; int nmem, i, error; @@ -254,6 +254,12 @@ ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t)); + /* We need the number of interrupt cells to read the imap */ + sc->sc_icells = 2; + if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) > 0) + OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells, + sizeof(sc->sc_icells)); + device_add_child(dev, "pci", device_get_unit(dev)); return (bus_generic_attach(dev)); } @@ -340,14 +346,15 @@ { struct grackle_softc *sc; struct ofw_pci_register reg; - uint32_t pintr, mintr; + uint32_t pintr, mintr[2]; uint8_t maskbuf[sizeof(reg) + sizeof(pintr)]; sc = device_get_softc(bus); pintr = pin; if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, ®, - sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf)) - return (mintr); + sizeof(reg), &pintr, sizeof(pintr), &mintr, + sizeof(mintr[0])*sc->sc_icells, maskbuf)) + return (mintr[0]); /* Maybe it's a real interrupt, not an intpin */ if (pin > 4) ==== //depot/projects/ppc-g5/sys/powerpc/powermac/gracklevar.h#3 (text+ko) ==== @@ -52,6 +52,7 @@ struct rman sc_mem_rman; bus_space_tag_t sc_memt; bus_dma_tag_t sc_dmat; + int sc_icells; struct ofw_bus_iinfo sc_pci_iinfo; }; ==== //depot/projects/ppc-g5/sys/powerpc/powermac/uninorth.c#7 (text+ko) ==== @@ -164,8 +164,7 @@ { struct uninorth_softc *sc; const char *compatible; - phandle_t node; - phandle_t child; + phandle_t node, child, iparent; u_int32_t reg[2], busrange[2]; struct uninorth_range *rp, *io, *mem[2]; int nmem, i, error; @@ -297,6 +296,12 @@ ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t)); + /* We need the number of interrupt cells to read the imap */ + sc->sc_icells = 2; + if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) > 0) + OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells, + sizeof(sc->sc_icells)); + device_add_child(dev, "pci", device_get_unit(dev)); return (bus_generic_attach(dev)); } @@ -365,14 +370,15 @@ { struct uninorth_softc *sc; struct ofw_pci_register reg; - uint32_t pintr, mintr; + uint32_t pintr, mintr[2]; uint8_t maskbuf[sizeof(reg) + sizeof(pintr)]; sc = device_get_softc(bus); pintr = pin; if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, ®, - sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf)) - return (mintr); + sizeof(reg), &pintr, sizeof(pintr), mintr, + sizeof(mintr[0])*sc->sc_icells, maskbuf)) + return (mintr[0]); /* Maybe it's a real interrupt, not an intpin */ if (pin > 4) ==== //depot/projects/ppc-g5/sys/powerpc/powermac/uninorthvar.h#6 (text+ko) ==== @@ -64,6 +64,7 @@ struct ofw_bus_iinfo sc_pci_iinfo; int sc_u3; + int sc_icells; }; struct unin_chip_softc {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811140448.mAE4mETa072066>