drivers: spi: nrfx: Prevent double nrfx_spi[m]_uninit calls

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 <andrzej.glabek@nordicsemi.no>
This commit is contained in:
Andrzej Głąbek 2020-02-12 11:38:09 +01:00 committed by Maureen Helm
commit 2b2a3b030f
2 changed files with 20 additions and 12 deletions

View file

@ -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) {

View file

@ -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) {