Skip to content

Commit 8cc8ccb

Browse files
affenull2345notro
authored andcommitted
drm/mipi-dbi: Lock SPI bus before setting D/C GPIO
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 <[email protected]> Reviewed-by: Noralf Trønnes <[email protected]> Acked-by: David Lechner <[email protected]> Signed-off-by: Noralf Trønnes <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 8e4bb53 commit 8cc8ccb

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

drivers/gpu/drm/drm_mipi_dbi.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,10 +1140,13 @@ static int mipi_dbi_typec3_command_read(struct mipi_dbi *dbi, u8 *cmd,
11401140
return -ENOMEM;
11411141

11421142
tr[1].rx_buf = buf;
1143+
1144+
spi_bus_lock(spi->controller);
11431145
gpiod_set_value_cansleep(dbi->dc, 0);
11441146

11451147
spi_message_init_with_transfers(&m, tr, ARRAY_SIZE(tr));
1146-
ret = spi_sync(spi, &m);
1148+
ret = spi_sync_locked(spi, &m);
1149+
spi_bus_unlock(spi->controller);
11471150
if (ret)
11481151
goto err_free;
11491152

@@ -1177,19 +1180,24 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd,
11771180

11781181
MIPI_DBI_DEBUG_COMMAND(*cmd, par, num);
11791182

1183+
spi_bus_lock(spi->controller);
11801184
gpiod_set_value_cansleep(dbi->dc, 0);
11811185
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
11821186
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1);
1187+
spi_bus_unlock(spi->controller);
11831188
if (ret || !num)
11841189
return ret;
11851190

11861191
if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes)
11871192
bpw = 16;
11881193

1194+
spi_bus_lock(spi->controller);
11891195
gpiod_set_value_cansleep(dbi->dc, 1);
11901196
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
1197+
ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
1198+
spi_bus_unlock(spi->controller);
11911199

1192-
return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
1200+
return ret;
11931201
}
11941202

11951203
/**
@@ -1271,7 +1279,8 @@ EXPORT_SYMBOL(mipi_dbi_spi_init);
12711279
* @len: Buffer length
12721280
*
12731281
* This SPI transfer helper breaks up the transfer of @buf into chunks which
1274-
* the SPI controller driver can handle.
1282+
* the SPI controller driver can handle. The SPI bus must be locked when
1283+
* calling this.
12751284
*
12761285
* Returns:
12771286
* Zero on success, negative error code on failure.
@@ -1305,7 +1314,7 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
13051314
buf += chunk;
13061315
len -= chunk;
13071316

1308-
ret = spi_sync(spi, &m);
1317+
ret = spi_sync_locked(spi, &m);
13091318
if (ret)
13101319
return ret;
13111320
}

drivers/gpu/drm/tiny/ili9225.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,19 +316,24 @@ static int ili9225_dbi_command(struct mipi_dbi *dbi, u8 *cmd, u8 *par,
316316
u32 speed_hz;
317317
int ret;
318318

319+
spi_bus_lock(spi->controller);
319320
gpiod_set_value_cansleep(dbi->dc, 0);
320321
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
321322
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1);
323+
spi_bus_unlock(spi->controller);
322324
if (ret || !num)
323325
return ret;
324326

325327
if (*cmd == ILI9225_WRITE_DATA_TO_GRAM && !dbi->swap_bytes)
326328
bpw = 16;
327329

330+
spi_bus_lock(spi->controller);
328331
gpiod_set_value_cansleep(dbi->dc, 1);
329332
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
333+
ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
334+
spi_bus_unlock(spi->controller);
330335

331-
return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
336+
return ret;
332337
}
333338

334339
static const struct drm_simple_display_pipe_funcs ili9225_pipe_funcs = {

drivers/gpu/drm/tiny/ili9486.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
5959
* before being transferred as 8-bit on the big endian SPI bus.
6060
*/
6161
buf[0] = cpu_to_be16(*cmd);
62+
spi_bus_lock(spi->controller);
6263
gpiod_set_value_cansleep(mipi->dc, 0);
6364
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 2);
6465
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, buf, 2);
66+
spi_bus_unlock(spi->controller);
6567
if (ret || !num)
6668
goto free;
6769

@@ -79,9 +81,11 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
7981
if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
8082
bpw = 16;
8183

84+
spi_bus_lock(spi->controller);
8285
gpiod_set_value_cansleep(mipi->dc, 1);
8386
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
8487
ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, data, num);
88+
spi_bus_unlock(spi->controller);
8589
free:
8690
kfree(buf);
8791

0 commit comments

Comments
 (0)