From 2b2a3b030fca08f8658c58b60d7ec9c8e46a251b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Wed, 12 Feb 2020 11:38:09 +0100 Subject: [PATCH] drivers: spi: nrfx: Prevent double nrfx_spi[m]_uninit calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attempt to deinitialize an nrfx driver that is not initialized results in an assertion failure reported by the driver. And such attempt could happen in SPI shims when the power state was switched between states other than ACTIVE. Signed-off-by: Andrzej Głąbek --- drivers/spi/spi_nrfx_spi.c | 16 ++++++++++------ drivers/spi/spi_nrfx_spim.c | 16 ++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index 8018e9115b2..85ba277c997 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -285,34 +285,38 @@ static int spi_nrfx_pm_control(struct device *dev, u32_t ctrl_command, void *context, device_pm_cb cb, void *arg) { int ret = 0; + struct spi_nrfx_data *data = get_dev_data(dev); + const struct spi_nrfx_config *config = get_dev_config(dev); if (ctrl_command == DEVICE_PM_SET_POWER_STATE) { u32_t new_state = *((const u32_t *)context); - if (new_state != get_dev_data(dev)->pm_state) { + if (new_state != data->pm_state) { switch (new_state) { case DEVICE_PM_ACTIVE_STATE: - init_spi(dev); + ret = init_spi(dev); /* Force reconfiguration before next transfer */ - get_dev_data(dev)->ctx.config = NULL; + data->ctx.config = NULL; break; case DEVICE_PM_LOW_POWER_STATE: case DEVICE_PM_SUSPEND_STATE: case DEVICE_PM_OFF_STATE: - nrfx_spi_uninit(&get_dev_config(dev)->spi); + if (data->pm_state == DEVICE_PM_ACTIVE_STATE) { + nrfx_spi_uninit(&config->spi); + } break; default: ret = -ENOTSUP; } if (!ret) { - get_dev_data(dev)->pm_state = new_state; + data->pm_state = new_state; } } } else { __ASSERT_NO_MSG(ctrl_command == DEVICE_PM_GET_POWER_STATE); - *((u32_t *)context) = get_dev_data(dev)->pm_state; + *((u32_t *)context) = data->pm_state; } if (cb) { diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 7074bdcbc12..1a2e1dbf497 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -324,34 +324,38 @@ static int spim_nrfx_pm_control(struct device *dev, u32_t ctrl_command, void *context, device_pm_cb cb, void *arg) { int ret = 0; + struct spi_nrfx_data *data = get_dev_data(dev); + const struct spi_nrfx_config *config = get_dev_config(dev); if (ctrl_command == DEVICE_PM_SET_POWER_STATE) { u32_t new_state = *((const u32_t *)context); - if (new_state != get_dev_data(dev)->pm_state) { + if (new_state != data->pm_state) { switch (new_state) { case DEVICE_PM_ACTIVE_STATE: - init_spim(dev); + ret = init_spim(dev); /* Force reconfiguration before next transfer */ - get_dev_data(dev)->ctx.config = NULL; + data->ctx.config = NULL; break; case DEVICE_PM_LOW_POWER_STATE: case DEVICE_PM_SUSPEND_STATE: case DEVICE_PM_OFF_STATE: - nrfx_spim_uninit(&get_dev_config(dev)->spim); + if (data->pm_state == DEVICE_PM_ACTIVE_STATE) { + nrfx_spim_uninit(&config->spim); + } break; default: ret = -ENOTSUP; } if (!ret) { - get_dev_data(dev)->pm_state = new_state; + data->pm_state = new_state; } } } else { __ASSERT_NO_MSG(ctrl_command == DEVICE_PM_GET_POWER_STATE); - *((u32_t *)context) = get_dev_data(dev)->pm_state; + *((u32_t *)context) = data->pm_state; } if (cb) {