Multiple displays may be connected to the same bus and share a D/C GPIO, so the display driver needs exclusive access to the bus to ensure that it can control the D/C GPIO safely. Signed-off-by: Otto Pflüger <otto.pflueger@xxxxxxxxx> --- drivers/gpu/drm/drm_mipi_dbi.c | 22 +++++++++++++++++----- include/drm/drm_mipi_dbi.h | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index c871d9f096b8..c205b7594571 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -1140,10 +1140,13 @@ static int mipi_dbi_typec3_command_read(struct mipi_dbi *dbi, u8 *cmd, return -ENOMEM; tr[1].rx_buf = buf; + + spi_bus_lock(spi->controller); gpiod_set_value_cansleep(dbi->dc, 0); spi_message_init_with_transfers(&m, tr, ARRAY_SIZE(tr)); - ret = spi_sync(spi, &m); + ret = spi_sync_locked(spi, &m); + spi_bus_unlock(spi->controller); if (ret) goto err_free; @@ -1177,19 +1180,24 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd, MIPI_DBI_DEBUG_COMMAND(*cmd, par, num); + spi_bus_lock(spi->controller); gpiod_set_value_cansleep(dbi->dc, 0); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); - ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1); + ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1, true); + spi_bus_unlock(spi->controller); if (ret || !num) return ret; if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes) bpw = 16; + spi_bus_lock(spi->controller); gpiod_set_value_cansleep(dbi->dc, 1); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); - return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num); + ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num, true); + spi_bus_unlock(spi->controller); + return ret; } /** @@ -1269,6 +1277,7 @@ EXPORT_SYMBOL(mipi_dbi_spi_init); * @bpw: Bits per word * @buf: Buffer to transfer * @len: Buffer length + * @is_locked: Is the SPI bus locked? * * This SPI transfer helper breaks up the transfer of @buf into chunks which * the SPI controller driver can handle. @@ -1277,7 +1286,7 @@ EXPORT_SYMBOL(mipi_dbi_spi_init); * Zero on success, negative error code on failure. */ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, - u8 bpw, const void *buf, size_t len) + u8 bpw, const void *buf, size_t len, bool is_locked) { size_t max_chunk = spi_max_transfer_size(spi); struct spi_transfer tr = { @@ -1305,7 +1314,10 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, buf += chunk; len -= chunk; - ret = spi_sync(spi, &m); + if (is_locked) + ret = spi_sync_locked(spi, &m); + else + ret = spi_sync(spi, &m); if (ret) return ret; } diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index 816f196b3d4c..da632288aff9 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -185,7 +185,7 @@ int mipi_dbi_poweron_conditional_reset(struct mipi_dbi_dev *dbidev); u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len); int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, - u8 bpw, const void *buf, size_t len); + u8 bpw, const void *buf, size_t len, bool is_locked); int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val); int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len); -- 2.39.1