Issue with SENSOR_DEVICE_DT_INST_DEFINE and PM_DEVICE_DT_INST_DEFINE: Power Management Callback Not Invoked

Hello,

I'm working on a project using the nRF52840 and Zephyr, and I'm experiencing an issue when trying to use device power management (PM) with a custom sensor driver.
Environment:

  • nRF Connect SDK v2.5.2

  • Toolchains v2.7.0

  • IDE: nRF Connect for VS Code extension

I am attaching a minimal project that reproduces the problem to facilitate support.

Device Definition

I am defining the device as follows in my driver:

#define KX132_SPI(inst) \
    (.spi = SPI_DT_SPEC_INST_GET(inst, SPI_OP_MODE_MASTER | \
        SPI_MODE_CPOL | SPI_TRANSFER_MSB | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), )

#define KX132_DEFINE(inst) \
    static struct kx132_data kx132_data_##inst; \
    static const struct kx132_device_config kx132_device_config_##inst = { \
        COND_CODE_1(DT_INST_ON_BUS(inst, spi), KX132_SPI(inst), ()) \
    }; \
    PM_DEVICE_DT_INST_DEFINE(inst, kx132_pm_action); \
    SENSOR_DEVICE_DT_INST_DEFINE(inst, kx132_init, PM_DEVICE_DT_INST_GET(inst), \
        &kx132_data_##inst, &kx132_device_config_##inst, APPLICATION, \
        CONFIG_SENSOR_INIT_PRIORITY, &kx132_driver_api);

This should correctly register the device with a power management callback (kx132_pm_action).
I'm also logging the following config macros at runtime to ensure they are enabled:

#ifdef CONFIG_PM_DEVICE
LOG_INF("CONFIG_PM_DEVICE");
#endif
#ifdef CONFIG_PM
LOG_INF("CONFIG_PM");
#endif
#ifdef CONFIG_PM_DEVICE_RUNTIME
LOG_INF("CONFIG_PM_DEVICE_RUNTIME");
#endif

All of these are active in my configuration and appear in the log during startup.


The Issue

When I attempt to turn off the device using the following code:

if (!device_is_ready(sensor)) {
    LOG_ERR("Sensor device not ready");
    return -ENODEV;
}

LOG_INF("Pointer do sensor: %p, nome: %s", sensor, sensor->name);

enum pm_device_state state;
int st_ret = pm_device_state_get(sensor, &state);
LOG_INF("Estado atual do sensor: %d, ret: %d", state, st_ret);

LOG_INF("Chamando PM_DEVICE_ACTION_TURN_OFF para o sensor");
int ret = pm_device_action_run(sensor, PM_DEVICE_ACTION_TURN_OFF);
LOG_INF("Resultado do PM_DEVICE_ACTION_TURN_OFF: %d", ret);

return ret;

I get the following log output:

<inf> ACCEL: Pointer do sensor: 0x35a44, nome: kx132@1
<inf> ACCEL: Estado atual do sensor: 0, ret: 0
<inf> ACCEL: Chamando PM_DEVICE_ACTION_TURN_OFF para o sensor
<inf> ACCEL: Resultado do PM_DEVICE_ACTION_TURN_OFF: -134

  • The pointer and device name match as expected.

  • The state of the device is ACTIVE (0).

  • However, calling pm_device_action_run() always returns -134 (-ENOTSUP).

  • The callback function kx132_pm_action() is never called (no log inside it appears).

What I Expect

  • I expect the PM callback (kx132_pm_action) to be called when I run pm_device_action_run(), but this does not happen.

  • All PM macros are enabled, the device is properly registered, and the device pointer is correct.

  • If I register the device using DEVICE_DT_INST_DEFINE instead of SENSOR_DEVICE_DT_INST_DEFINE, the PM callback is called as expected.


Suspected Problem

It seems that SENSOR_DEVICE_DT_INST_DEFINE (and possibly SENSOR_DEVICE_DT_DEFINE) is not properly associating the PM structure with the device, or Zephyr is not enabling PM for this sensor device, despite all settings appearing to be correct.


Steps to Reproduce

  1. Use the macros shown above in a sensor driver.

  2. Build with CONFIG_PM, CONFIG_PM_DEVICE, and CONFIG_PM_DEVICE_RUNTIME enabled.

  3. Call pm_device_action_run() for the sensor device.

  4. Observe that the PM callback is not called and the return is always -ENOTSUP.


Could you clarify if this is a bug, a missing configuration, or if there are additional requirements for enabling PM for sensors defined with SENSOR_DEVICE_DT_INST_DEFINE?

I'm attaching the minimal project that reproduces the issue.

Thanks in advance!

pm_device.zip

Related