Skip to content

drivers: modem: cellular: select GPIO - #2

Open
ShahriarAhnaf wants to merge 1 commit into
mainfrom
fix/modem-cellular-select-gpio
Open

drivers: modem: cellular: select GPIO#2
ShahriarAhnaf wants to merge 1 commit into
mainfrom
fix/modem-cellular-select-gpio

Conversation

@ShahriarAhnaf

@ShahriarAhnaf ShahriarAhnaf commented Aug 27, 2026

Copy link
Copy Markdown

Review copy, scoped to this fork only. Not intended to be opened against zephyrproject-rtos/zephyr yet.

modem_cellular_init() calls gpio_pin_configure_dt() for the wake, power, reset and ring GPIOs, and the bindings mark mdm-power-gpios/mdm-reset-gpios as required. MODEM_CELLULAR selects the modem modules, PPP, CMUX, CHAT, the UART backend and the ring buffer, but not GPIO.

CONFIG_GPIO has no default, so an application that does not enable it explicitly still builds. samples/net/cellular_modem is one such application: configuring it for b_u585i_iot02a leaves CONFIG_GPIO unset in the resulting .config. The GPIO driver is then not built, the gpio_dt_spec device pointers reference a device with no API, and the first gpio_pin_configure_dt() in the driver's init function faults before the modem is ever powered on.

Select GPIO from MODEM_CELLULAR, the same way the driver already selects everything else it calls into. 78 drivers in drivers/ that dereference a GPIO unconditionally use select GPIO.

Found booting the sample on a simulated STM32 with a simulated modem: usage fault at t=0, before any AT traffic.

Reproduced on real silicon, not just simulation: built samples/net/cellular_modem for nucleo_f401re with a quectel,bg95 modem node (mdm-power-gpios set, CONFIG_GPIO left unselected — confirmed absent from the resulting .config) and flashed it to a real Nucleo-F401RE over ST-LINK/OpenOCD. The board hard-faults at boot. Attaching GDB over the debug probe gives an unambiguous backtrace:

#0  arch_system_halt (reason=20) at kernel/fatal.c:30
#1  k_sys_fatal_error_handler (reason=20, ...) at kernel/fatal.c:44
#2  z_fatal_error (reason=20, ...) at kernel/fatal.c:119
#3  z_arm_fatal_error (reason=20, ...) at arch/arm/core/fatal.c:93
#4  z_arm_fault (...) at arch/arm/core/cortex_m/fault.c:1090
#5  z_arm_usage_fault () at arch/arm/core/cortex_m/fault_s.S:103
#6  <signal handler called>
#8  modem_cellular_init (dev=...) at drivers/modem/modem_cellular.c:2320

Frame 8, line 2320, is gpio_pin_configure_dt(&config->power_gpio, GPIO_OUTPUT_INACTIVE) — exactly the call this PR guards with select GPIO. Flash/RAM utilization on that build was 32.59% / 48.18%, so this isn't a resource-exhaustion artifact; it's a clean, reproducible UsageFault from calling into a driver that was never linked in. The same class of bug was independently hit (and worked around by hand with an explicit CONFIG_GPIO=y) building our own nucleo_f767zi + cellular-modem fixture before this fix existed, so it isn't specific to F401 either — every non-Nordic board we've tried this on that doesn't force CONFIG_GPIO=y at the board level reproduces it. (Note: in-tree Nordic nRF52840 boards all hard-code CONFIG_GPIO=y in their board defconfig for onboard LEDs/buttons, which happens to mask this bug on that hardware family specifically.)

Verified: grep GPIO build/zephyr/.config shows # CONFIG_GPIO is not set before, CONFIG_GPIO=y after. checkpatch clean.

modem_cellular_init() unconditionally calls gpio_pin_configure_dt() for
the wake, power, reset and ring GPIOs of the modem, and the bindings
mark mdm-power-gpios and mdm-reset-gpios as required. MODEM_CELLULAR
however only selects the modem modules, PPP, CMUX, CHAT, the UART
backend and the ring buffer, not GPIO.

CONFIG_GPIO has no default, so an application that does not enable it
explicitly still builds. samples/net/cellular_modem is such an
application: configuring it for b_u585i_iot02a leaves CONFIG_GPIO unset
in the resulting .config. The GPIO driver is then not built, the
gpio_dt_spec device pointers reference a device with no API, and the
first gpio_pin_configure_dt() call in the driver's init function faults
before the modem is ever powered on.

Select GPIO from MODEM_CELLULAR, the same way the driver already
selects everything else it calls into. This matches how other drivers
that dereference a GPIO unconditionally handle the dependency.

Signed-off-by: Ahnaf Shahriar <shahriarahnaf007@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant