spi: Restore delays for non-GPIO chip select

[ Upstream commit aa0162dc0d ]

SPI controller with integrated chip select handling still need to adhere
to SPI device's CS setup, hold and inactive delays. For controller
without set_cs_timing spi core shall handle the delays to avoid
duplicated delay handling in each controller driver.
Fixes a regression for the out of tree SPI controller and SPI HID
transport on Apple M1/M1 Pro/Max notebooks.

Fixes: 4d8ff6b099 ("spi: Add multi-cs memories support in SPI core")
Signed-off-by: Janne Grunau <j@jannau.net>
Link: https://msgid.link/r/20240311-spi-cs-delays-regression-v1-1-0075020a90b2@jannau.net
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Janne Grunau 2024-03-11 23:53:17 +01:00 committed by Sasha Levin
parent 996ce83960
commit 55ed48c68e

View file

@ -1042,10 +1042,14 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
enable = !enable; enable = !enable;
if (spi_is_csgpiod(spi)) { /*
if (!spi->controller->set_cs_timing && !activate) * Handle chip select delays for GPIO based CS or controllers without
spi_delay_exec(&spi->cs_hold, NULL); * programmable chip select timing.
*/
if ((spi_is_csgpiod(spi) || !spi->controller->set_cs_timing) && !activate)
spi_delay_exec(&spi->cs_hold, NULL);
if (spi_is_csgpiod(spi)) {
if (!(spi->mode & SPI_NO_CS)) { if (!(spi->mode & SPI_NO_CS)) {
/* /*
* Historically ACPI has no means of the GPIO polarity and * Historically ACPI has no means of the GPIO polarity and
@ -1079,16 +1083,16 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
if ((spi->controller->flags & SPI_CONTROLLER_GPIO_SS) && if ((spi->controller->flags & SPI_CONTROLLER_GPIO_SS) &&
spi->controller->set_cs) spi->controller->set_cs)
spi->controller->set_cs(spi, !enable); spi->controller->set_cs(spi, !enable);
if (!spi->controller->set_cs_timing) {
if (activate)
spi_delay_exec(&spi->cs_setup, NULL);
else
spi_delay_exec(&spi->cs_inactive, NULL);
}
} else if (spi->controller->set_cs) { } else if (spi->controller->set_cs) {
spi->controller->set_cs(spi, !enable); spi->controller->set_cs(spi, !enable);
} }
if (spi_is_csgpiod(spi) || !spi->controller->set_cs_timing) {
if (activate)
spi_delay_exec(&spi->cs_setup, NULL);
else
spi_delay_exec(&spi->cs_inactive, NULL);
}
} }
#ifdef CONFIG_HAS_DMA #ifdef CONFIG_HAS_DMA