From d2fdf52d439228f9d779f6bc4256cb9a9f836a87 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 20 May 2025 11:59:35 -0700 Subject: [PATCH] drivers: sensor: bmm350: fix handling interrupt race condition There is a race condition where an interrupt can fire before the drdy_handler is registered. The drdy_handler will tradionaly callback the sample get clearing the interrupt... but if it's not configured and NULL, the interrupt will stay forever latched. Read the interrupt status to clear the interrupt flag allowing it to trigger again. Also, move the serial api function helpers in to the header allowing them to be used from other c files. Signed-off-by: Ryan McClelland --- drivers/sensor/bosch/bmm350/bmm350.c | 21 ----------------- drivers/sensor/bosch/bmm350/bmm350.h | 24 +++++++++++++++++++- drivers/sensor/bosch/bmm350/bmm350_trigger.c | 17 +++++++++++--- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/drivers/sensor/bosch/bmm350/bmm350.c b/drivers/sensor/bosch/bmm350/bmm350.c index ffde7e4bba7..44b96a34aaf 100644 --- a/drivers/sensor/bosch/bmm350/bmm350.c +++ b/drivers/sensor/bosch/bmm350/bmm350.c @@ -14,27 +14,6 @@ LOG_MODULE_REGISTER(BMM350, CONFIG_SENSOR_LOG_LEVEL); -static inline int bmm350_bus_check(const struct device *dev) -{ - const struct bmm350_config *cfg = dev->config; - - return cfg->bus_io->check(&cfg->bus); -} - -static inline int bmm350_reg_read(const struct device *dev, uint8_t start, uint8_t *buf, int size) -{ - const struct bmm350_config *cfg = dev->config; - - return cfg->bus_io->read(&cfg->bus, start, buf, size); -} - -int bmm350_reg_write(const struct device *dev, uint8_t reg, uint8_t val) -{ - const struct bmm350_config *cfg = dev->config; - - return cfg->bus_io->write(&cfg->bus, reg, val); -} - static int8_t bmm350_read_otp_word(const struct device *dev, uint8_t addr, uint16_t *lsb_msb) { int8_t ret = 0; diff --git a/drivers/sensor/bosch/bmm350/bmm350.h b/drivers/sensor/bosch/bmm350/bmm350.h index 7ce36d9b575..a6acbdbed11 100644 --- a/drivers/sensor/bosch/bmm350/bmm350.h +++ b/drivers/sensor/bosch/bmm350/bmm350.h @@ -495,5 +495,27 @@ int bmm350_trigger_mode_init(const struct device *dev); int bmm350_trigger_set(const struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler); -int bmm350_reg_write(const struct device *dev, uint8_t reg, uint8_t val); + +/* inline helper functions */ +static inline int bmm350_bus_check(const struct device *dev) +{ + const struct bmm350_config *cfg = dev->config; + + return cfg->bus_io->check(&cfg->bus); +} + +static inline int bmm350_reg_read(const struct device *dev, uint8_t start, uint8_t *buf, int size) +{ + const struct bmm350_config *cfg = dev->config; + + return cfg->bus_io->read(&cfg->bus, start, buf, size); +} + +static inline int bmm350_reg_write(const struct device *dev, uint8_t reg, uint8_t val) +{ + const struct bmm350_config *cfg = dev->config; + + return cfg->bus_io->write(&cfg->bus, reg, val); +} + #endif /* __SENSOR_BMM350_H__ */ diff --git a/drivers/sensor/bosch/bmm350/bmm350_trigger.c b/drivers/sensor/bosch/bmm350/bmm350_trigger.c index 03624de81f0..700f38a142d 100644 --- a/drivers/sensor/bosch/bmm350/bmm350_trigger.c +++ b/drivers/sensor/bosch/bmm350/bmm350_trigger.c @@ -15,14 +15,25 @@ LOG_MODULE_DECLARE(BMM350, CONFIG_SENSOR_LOG_LEVEL); -static void bmm350_handle_interrupts(const void *arg) +static int bmm350_handle_interrupts(const void *arg) { const struct device *dev = (const struct device *)arg; struct bmm350_data *data = dev->data; + uint8_t intr_status; + int ret; + + /* Read interrupt status to clear interrupt */ + ret = bmm350_reg_read(dev, BMM350_REG_INT_STATUS, &intr_status, sizeof(intr_status)); + if (ret < 0) { + LOG_ERR("%s: failed to read interrupt status", dev->name); + return ret; + } if (data->drdy_handler) { data->drdy_handler(dev, data->drdy_trigger); } + + return 0; } #ifdef CONFIG_BMM350_TRIGGER_OWN_THREAD @@ -38,7 +49,7 @@ static void bmm350_thread_main(void *arg1, void *unused1, void *unused2) while (1) { k_sem_take(&data->sem, K_FOREVER); - bmm350_handle_interrupts(dev); + (void)bmm350_handle_interrupts(dev); } } #endif @@ -48,7 +59,7 @@ static void bmm350_work_handler(struct k_work *work) { struct bmm350_data *data = CONTAINER_OF(work, struct bmm350_data, work); - bmm350_handle_interrupts(data->dev); + (void)bmm350_handle_interrupts(data->dev); } #endif