diff options
Diffstat (limited to 'sys/pci/intpm.c')
-rw-r--r-- | sys/pci/intpm.c | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/sys/pci/intpm.c b/sys/pci/intpm.c index 9e1f59b..397376e 100644 --- a/sys/pci/intpm.c +++ b/sys/pci/intpm.c @@ -104,9 +104,12 @@ intsmb_probe(device_t dev) device_set_desc(dev, "ATI IXP400 SMBus Controller"); break; case 0x43851002: - case 0x780b1022: /* AMD Hudson */ - device_set_desc(dev, "AMD SB600/7xx/8xx SMBus Controller"); - /* XXX Maybe force polling right here? */ + device_set_desc(dev, "AMD SB600/7xx/8xx/9xx SMBus Controller"); + break; + case 0x780b1022: /* AMD FCH */ + if (pci_get_revid(dev) < 0x40) + return (ENXIO); + device_set_desc(dev, "AMD FCH SMBus Controller"); break; default: return (ENXIO); @@ -196,6 +199,23 @@ sb8xx_attach(device_t dev) return (0); } +static void +intsmb_release_resources(device_t dev) +{ + struct intsmb_softc *sc = device_get_softc(dev); + + if (sc->smbus) + device_delete_child(dev, sc->smbus); + if (sc->irq_hand) + bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); + if (sc->irq_res) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); + if (sc->io_res) + bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, + sc->io_res); + mtx_destroy(&sc->lock); +} + static int intsmb_attach(device_t dev) { @@ -218,10 +238,12 @@ intsmb_attach(device_t dev) break; #endif case 0x43851002: - case 0x780b1022: if (pci_get_revid(dev) >= 0x40) sc->sb8xx = 1; break; + case 0x780b1022: + sc->sb8xx = 1; + break; } if (sc->sb8xx) { @@ -306,12 +328,15 @@ no_intr: sc->isbusy = 0; sc->smbus = device_add_child(dev, "smbus", -1); if (sc->smbus == NULL) { + device_printf(dev, "failed to add smbus child\n"); error = ENXIO; goto fail; } error = device_probe_and_attach(sc->smbus); - if (error) + if (error) { + device_printf(dev, "failed to probe+attach smbus child\n"); goto fail; + } #ifdef ENABLE_ALART /* Enable Arart */ @@ -320,30 +345,22 @@ no_intr: return (0); fail: - intsmb_detach(dev); + intsmb_release_resources(dev); return (error); } static int intsmb_detach(device_t dev) { - struct intsmb_softc *sc = device_get_softc(dev); int error; error = bus_generic_detach(dev); - if (error) + if (error) { + device_printf(dev, "bus detach failed\n"); return (error); + } - if (sc->smbus) - device_delete_child(dev, sc->smbus); - if (sc->irq_hand) - bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); - if (sc->io_res) - bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, - sc->io_res); - mtx_destroy(&sc->lock); + intsmb_release_resources(dev); return (0); } @@ -907,7 +924,8 @@ static driver_t intsmb_driver = { sizeof(struct intsmb_softc), }; -DRIVER_MODULE(intsmb, pci, intsmb_driver, intsmb_devclass, 0, 0); +DRIVER_MODULE_ORDERED(intsmb, pci, intsmb_driver, intsmb_devclass, 0, 0, + SI_ORDER_ANY); DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0); MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); MODULE_VERSION(intsmb, 1); |