summaryrefslogtreecommitdiffstats
path: root/sys/pci/intpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pci/intpm.c')
-rw-r--r--sys/pci/intpm.c56
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);
OpenPOWER on IntegriCloud