Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <otto.pflueger@abscue.de>
Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
Acked-by: David Lechner <david@lechnology.com>
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230724065654.5269-2-otto.pflueger@abscue.de

authored by

Otto Pflüger and committed by
Noralf Trønnes
8cc8ccba 8e4bb53c

+23 -5
+13 -4
drivers/gpu/drm/drm_mipi_dbi.c
··· 1140 1140 return -ENOMEM; 1141 1141 1142 1142 tr[1].rx_buf = buf; 1143 + 1144 + spi_bus_lock(spi->controller); 1143 1145 gpiod_set_value_cansleep(dbi->dc, 0); 1144 1146 1145 1147 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); 1147 1150 if (ret) 1148 1151 goto err_free; 1149 1152 ··· 1180 1177 1181 1178 MIPI_DBI_DEBUG_COMMAND(*cmd, par, num); 1182 1179 1180 + spi_bus_lock(spi->controller); 1183 1181 gpiod_set_value_cansleep(dbi->dc, 0); 1184 1182 speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); 1185 1183 ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1); 1184 + spi_bus_unlock(spi->controller); 1186 1185 if (ret || !num) 1187 1186 return ret; 1188 1187 1189 1188 if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes) 1190 1189 bpw = 16; 1191 1190 1191 + spi_bus_lock(spi->controller); 1192 1192 gpiod_set_value_cansleep(dbi->dc, 1); 1193 1193 speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); 1194 + ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num); 1195 + spi_bus_unlock(spi->controller); 1194 1196 1195 - return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num); 1197 + return ret; 1196 1198 } 1197 1199 1198 1200 /** ··· 1279 1271 * @len: Buffer length 1280 1272 * 1281 1273 * This SPI transfer helper breaks up the transfer of @buf into chunks which 1282 - * the SPI controller driver can handle. 1274 + * the SPI controller driver can handle. The SPI bus must be locked when 1275 + * calling this. 1283 1276 * 1284 1277 * Returns: 1285 1278 * Zero on success, negative error code on failure. ··· 1314 1305 buf += chunk; 1315 1306 len -= chunk; 1316 1307 1317 - ret = spi_sync(spi, &m); 1308 + ret = spi_sync_locked(spi, &m); 1318 1309 if (ret) 1319 1310 return ret; 1320 1311 }
+6 -1
drivers/gpu/drm/tiny/ili9225.c
··· 316 316 u32 speed_hz; 317 317 int ret; 318 318 319 + spi_bus_lock(spi->controller); 319 320 gpiod_set_value_cansleep(dbi->dc, 0); 320 321 speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); 321 322 ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1); 323 + spi_bus_unlock(spi->controller); 322 324 if (ret || !num) 323 325 return ret; 324 326 325 327 if (*cmd == ILI9225_WRITE_DATA_TO_GRAM && !dbi->swap_bytes) 326 328 bpw = 16; 327 329 330 + spi_bus_lock(spi->controller); 328 331 gpiod_set_value_cansleep(dbi->dc, 1); 329 332 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); 330 335 331 - return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num); 336 + return ret; 332 337 } 333 338 334 339 static const struct drm_simple_display_pipe_funcs ili9225_pipe_funcs = {
+4
drivers/gpu/drm/tiny/ili9486.c
··· 59 59 * before being transferred as 8-bit on the big endian SPI bus. 60 60 */ 61 61 buf[0] = cpu_to_be16(*cmd); 62 + spi_bus_lock(spi->controller); 62 63 gpiod_set_value_cansleep(mipi->dc, 0); 63 64 speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 2); 64 65 ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, buf, 2); 66 + spi_bus_unlock(spi->controller); 65 67 if (ret || !num) 66 68 goto free; 67 69 ··· 81 79 if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes) 82 80 bpw = 16; 83 81 82 + spi_bus_lock(spi->controller); 84 83 gpiod_set_value_cansleep(mipi->dc, 1); 85 84 speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); 86 85 ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, data, num); 86 + spi_bus_unlock(spi->controller); 87 87 free: 88 88 kfree(buf); 89 89