Skip to content
Snippets Groups Projects
Commit ea95e922 authored by Dmitry Osipenko's avatar Dmitry Osipenko
Browse files

WIP: mfd: rk8xx: Use atomic SPI transfer for power-off

parent 59ec8ff7
No related branches found
No related tags found
No related merge requests found
...@@ -634,7 +634,7 @@ static int rk808_power_off(struct sys_off_data *data) ...@@ -634,7 +634,7 @@ static int rk808_power_off(struct sys_off_data *data)
default: default:
return NOTIFY_DONE; return NOTIFY_DONE;
} }
ret = regmap_update_bits(rk808->regmap, reg, bit, bit); ret = regmap_update_bits_atomic(rk808->regmap, reg, bit, bit);
if (ret) if (ret)
dev_err(rk808->dev, "Failed to shutdown device!\n"); dev_err(rk808->dev, "Failed to shutdown device!\n");
......
...@@ -38,6 +38,12 @@ static const struct regmap_config rk806_regmap_config_spi = { ...@@ -38,6 +38,12 @@ static const struct regmap_config rk806_regmap_config_spi = {
.volatile_table = &rk806_volatile_table, .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) static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
{ {
struct device *dev = context; struct device *dev = context;
...@@ -57,6 +63,9 @@ static int rk806_spi_bus_write(void *context, const void *vdata, size_t count) ...@@ -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].tx_buf = vdata;
xfer[1].len = count; 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)); 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, ...@@ -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); txbuf[0] = RK806_CMD_WITH_SIZE(READ, val_size);
memcpy(txbuf+1, vreg, reg_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); return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment