gpioiic_attach: fix a NULL pointer crash on hints-based systems
The attach method uses GPIO_GET_BUS() to get a "newbus" device that provides a pin. But on hints-based systems a GPIO controller driver might not be fully initialized yet and it does not know gpiobus hanging off it. Thus, GPIO_GET_BUS() cannot be called yet. The reason is that controller drivers typically create a child gpiobus using gpiobus_attach_bus() and that leads to the following call chain: gpiobus_attach_bus() -> gpiobus_attach() -> bus_generic_attach(gpiobus) -> gpioiic_attach(). So, gpioiic_attach() is called before gpiobus_attach_bus() returns. I observed this bug with nctgpio driver on amd64. I think that the problem was introduced in r355276. The fix is to avoid calling GPIO_GET_BUS() from the attach method. Instead, we know that on hints-based systems only the parent gpiobus can provide the pins. Nothing is changed for FDT-based systems. MFC after: 1 week
This commit is contained in:
parent
e47f1857b2
commit
20077ec02c
@ -303,10 +303,20 @@ gpioiic_attach(device_t dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Say what we came up with for pin config. */
|
||||
/*
|
||||
* Say what we came up with for pin config.
|
||||
* NB: in the !FDT case the controller driver might not be set up enough
|
||||
* for GPIO_GET_BUS() to work. Also, our parent is the only gpiobus
|
||||
* that can provide our pins.
|
||||
*/
|
||||
device_printf(dev, "SCL pin: %s:%d, SDA pin: %s:%d\n",
|
||||
#ifdef FDT
|
||||
device_get_nameunit(GPIO_GET_BUS(sc->sclpin->dev)), sc->sclpin->pin,
|
||||
device_get_nameunit(GPIO_GET_BUS(sc->sdapin->dev)), sc->sdapin->pin);
|
||||
#else
|
||||
device_get_nameunit(device_get_parent(dev)), sc->sclpin->pin,
|
||||
device_get_nameunit(device_get_parent(dev)), sc->sdapin->pin);
|
||||
#endif
|
||||
|
||||
/* Add the bitbang driver as our only child; it will add iicbus. */
|
||||
device_add_child(sc->dev, "iicbb", -1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user