drivers: mfd: npm1300: Fixed race condition in event callback
If an event occurs between the status registers being read and the event being cleared, the interrupt line will remain active. As the interrupt is edge triggered, all future interrupts will being ignored. This problem will also occur if an I2C transation fails in the callback. The state of the interrupt pin is now checked at the end of the callback, and a retry is attempted if the interrupt has not been cleared. Signed-off-by: Andy Sinclair <andy.sinclair@nordicsemi.no>
This commit is contained in:
parent
733834851d
commit
7cf4eff731
1 changed files with 8 additions and 0 deletions
|
|
@ -79,12 +79,14 @@ static void gpio_callback(const struct device *dev, struct gpio_callback *cb, ui
|
|||
static void work_callback(struct k_work *work)
|
||||
{
|
||||
struct mfd_npm1300_data *data = CONTAINER_OF(work, struct mfd_npm1300_data, work);
|
||||
const struct mfd_npm1300_config *config = data->dev->config;
|
||||
uint8_t buf[MAIN_SIZE];
|
||||
int ret;
|
||||
|
||||
/* Read all MAIN registers into temporary buffer */
|
||||
ret = mfd_npm1300_reg_read_burst(data->dev, MAIN_BASE, 0U, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
k_work_submit(&data->work);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -97,10 +99,16 @@ static void work_callback(struct k_work *work)
|
|||
ret = mfd_npm1300_reg_write(data->dev, MAIN_BASE, offset,
|
||||
event_reg[i].mask);
|
||||
if (ret < 0) {
|
||||
k_work_submit(&data->work);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Resubmit handler to queue if interrupt is still active */
|
||||
if (gpio_pin_get_dt(&config->host_int_gpios) != 0) {
|
||||
k_work_submit(&data->work);
|
||||
}
|
||||
}
|
||||
|
||||
static int mfd_npm1300_init(const struct device *dev)
|
||||
|
|
|
|||
Loading…
Reference in a new issue