I’ve developed a device tree overlay to describe some pieces of my embedded system. The system is comprised of a Raspberry Pi, a separate custom circuit board with a few I2C devices, and a power supply. While the Raspberry Pi gets power all the time, the separate circuit board only gets power when it’s enabled externally. Now, if the separate circuit board is powered when the Pi boots, the device tree overlay works flawlessly, and all I2C devices on the separate circuit board work properly. However, if the Pi boots before the separate circuit board is powered, the kernel log shows
[ 17.630787] i2c 1-0040: deferred probe pending
and obviously I cannot communicate with the I2C devices.
Now, if I remove the dtoverlay from /boot/firmware/config.txt and try to load the overlay dynamically at runtime (after the circuit board has power), one of the drivers fails to load with the following messages in dmesg:
[ 43.227575] tps25990 1-0040: Found fault-gpio
[ 43.227586] tps25990 1-0040: Found fault-gpio at gpio586
[ 43.227593] tps25990 1-0040: fault-gpio is mapped to IRQ-6
[ 43.227598] tps25990 1-0040: irq_set_irq_type returns -22
[ 43.227604] tps25990 1-0040: Failed to request fault-gpio irq (code: -22)
[ 43.227615] tps25990: probe of 1-0040 failed with error -22
For reference, here’s the relevant lines of code from the driver:
data->fault_gpio = devm_gpiod_get_optional(&client->dev, "fault", GPIOD_IN);
if (data->fault_gpio) {
dev_info(&client->dev, "Found fault-gpio at gpio%dn", desc_to_gpio(data->fault_gpio));
gpiod_set_consumer_name(data->fault_gpio, "EFUSE FAULT");
data->fault_gpio_irq = gpiod_to_irq(data->fault_gpio);
if (data->fault_gpio_irq < 0) {
dev_err(&client->dev, "No corresponding irq for fault-gpion");
return data->fault_gpio_irq;
} else {
dev_info(&client->dev, "fault-gpio is mapped to IRQ%dn", data->fault_gpio_irq);
}
ret = irq_set_irq_type(data->fault_gpio_irq, IRQ_TYPE_EDGE_FALLING);
dev_dbg(&client->dev, "irq_set_irq_type returns %dn", ret);
ret = devm_request_threaded_irq(&client->dev,
data->fault_gpio_irq,
NULL,
efuse_fault_gpio_irq_handler,
0,
"efuse fault",
data);
if (ret) {
dev_err(&client->dev, "Failed to request fault-gpio irq (code: %d)n", ret);
irq_dispose_mapping(data->fault_gpio_irq);
return ret;
}
} else {
dev_info(&client->dev, "No fault-gpio found in device treen");
}
So it appears that irq_set_irq_type
fails when loading the dtoverlay dynamically. Does anyone have suggestions on how to correct this?