diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c index 71c2b80a4678d627e86cfbec8135f08e262559d3..8e0d32582e17f162a9a201f8f92f23214d833644 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c @@ -634,7 +634,7 @@ static int rk808_power_off(struct sys_off_data *data) default: return NOTIFY_DONE; } - ret = regmap_update_bits(rk808->regmap, reg, bit, bit); + ret = regmap_update_bits_atomic(rk808->regmap, reg, bit, bit); if (ret) dev_err(rk808->dev, "Failed to shutdown device!\n"); diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c index 3405fb82ff9fbcf96743dc6cd3c61f38a108ca29..2812a5429e4c0d99c2a1e093950938cc6d2901b4 100644 --- a/drivers/mfd/rk8xx-spi.c +++ b/drivers/mfd/rk8xx-spi.c @@ -38,6 +38,12 @@ static const struct regmap_config rk806_regmap_config_spi = { .volatile_table = &rk806_volatile_table, }; +static inline bool in_atomic_xfer_mode(void) +{ + return system_state > SYSTEM_RUNNING && + (IS_ENABLED(CONFIG_PREEMPT_COUNT) ? !preemptible() : irqs_disabled()); +} + static int rk806_spi_bus_write(void *context, const void *vdata, size_t count) { struct device *dev = context; @@ -57,6 +63,9 @@ static int rk806_spi_bus_write(void *context, const void *vdata, size_t count) xfer[1].tx_buf = vdata; xfer[1].len = count; + if (in_atomic_xfer_mode()) + return spi_sync_transfer_atomic(spi, xfer, ARRAY_SIZE(xfer)); + return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer)); } @@ -75,6 +84,10 @@ static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size, txbuf[0] = RK806_CMD_WITH_SIZE(READ, val_size); memcpy(txbuf+1, vreg, reg_size); + if (in_atomic_xfer_mode()) + return spi_write_then_read_atomic(spi, txbuf, sizeof(txbuf), + val, val_size); + return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size); }