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 <ryanmcclelland@meta.com>
This commit is contained in:
parent
c7e1f0b3da
commit
d2fdf52d43
@ -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;
|
||||
|
||||
@ -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__ */
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user