summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2019-12-05 12:13:40 +0300
committerMark Brown <broonie@kernel.org>2019-12-09 21:46:34 +0300
commit4a07b8bcd503c842bcf0171cdbccdfdac3d985c3 (patch)
treeaaa3ab1ae1173dfd6384024cda28fed155b0db5a
parent8a6553ecdf976d6a34664bd491f0ea74a15aa982 (diff)
downloadlinux-4a07b8bcd503c842bcf0171cdbccdfdac3d985c3.tar.xz
spi: bitbang: Make chipselect callback optional
The ->chipselect() callback on the bit-banged SPI library master is optional if using GPIO descriptors: when using descriptors exclusively without any native chipselects, the core does not even call out the the native ->set_cs() and therefore ->chipselect() on a bit-banged SPI master will not even be called in this case. Make sure to respect the SPI_MASTER_GPIO_SS as used by e.g. spi-gpio.c though: this setting will make the core handle the chip select using GPIO descriptors *AND* call the local chipselect handler. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20191205091340.59850-1-linus.walleij@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-bitbang.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index d84e22dd6f9f..68491a8bf7b5 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -329,8 +329,20 @@ static void spi_bitbang_set_cs(struct spi_device *spi, bool enable)
int spi_bitbang_init(struct spi_bitbang *bitbang)
{
struct spi_master *master = bitbang->master;
+ bool custom_cs;
- if (!master || !bitbang->chipselect)
+ if (!master)
+ return -EINVAL;
+ /*
+ * We only need the chipselect callback if we are actually using it.
+ * If we just use GPIO descriptors, it is surplus. If the
+ * SPI_MASTER_GPIO_SS flag is set, we always need to call the
+ * driver-specific chipselect routine.
+ */
+ custom_cs = (!master->use_gpio_descriptors ||
+ (master->flags & SPI_MASTER_GPIO_SS));
+
+ if (custom_cs && !bitbang->chipselect)
return -EINVAL;
mutex_init(&bitbang->lock);
@@ -344,7 +356,12 @@ int spi_bitbang_init(struct spi_bitbang *bitbang)
master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
master->transfer_one = spi_bitbang_transfer_one;
- master->set_cs = spi_bitbang_set_cs;
+ /*
+ * When using GPIO descriptors, the ->set_cs() callback doesn't even
+ * get called unless SPI_MASTER_GPIO_SS is set.
+ */
+ if (custom_cs)
+ master->set_cs = spi_bitbang_set_cs;
if (!bitbang->txrx_bufs) {
bitbang->use_dma = 0;