[PATCH 1/2] drm/mipi-dbi: Lock SPI bus before setting D/C GPIO
Otto Pflüger
otto.pflueger at abscue.de
Wed Jul 19 09:53:42 UTC 2023
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 at abscue.de>
---
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
More information about the dri-devel
mailing list