From ed14666c3f877c4c2a428a92bfeebfba3a4cfe2e Mon Sep 17 00:00:00 2001 From: Nathan Rossi Date: Mon, 16 Aug 2021 05:02:28 +0000 Subject: spi: orion: Prevent incorrect chip select behaviour When clearing the chip-select mask, the controller will switch to chip selecting the native CS0 line. Because the control register chip-select mask is not updated in a single write this will cause undesirable chip-selection of CS0 even when requesting to select other native chip-select lines. This is additionally problematic as the chip-select may still be asserted. With the ARMADA 38x SoC the controller will assert both the desired native chip-select and CS0. To avoid any undesirable behaviour with the chip-select lines, update the control register with a single write. This avoids selecting CS0 and causes the (de-)assert to apply at the same time. Signed-off-by: Nathan Rossi Link: https://lore.kernel.org/r/20210816050228.3223661-1-nathan@nathanrossi.com Signed-off-by: Mark Brown --- drivers/spi/spi-orion.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 34b31aba3981..e8de3cbbfb2a 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -328,8 +328,16 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) static void orion_spi_set_cs(struct spi_device *spi, bool enable) { struct orion_spi *orion_spi; + void __iomem *ctrl_reg; + u32 val; orion_spi = spi_master_get_devdata(spi->master); + ctrl_reg = spi_reg(orion_spi, ORION_SPI_IF_CTRL_REG); + + val = readl(ctrl_reg); + + /* Clear existing chip-select and assertion state */ + val &= ~(ORION_SPI_CS_MASK | 0x1); /* * If this line is using a GPIO to control chip select, this internal @@ -338,9 +346,7 @@ static void orion_spi_set_cs(struct spi_device *spi, bool enable) * as it is handled by a GPIO, but that doesn't matter. What we need * is to deassert the old chip select and assert some other chip select. */ - orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK); - orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, - ORION_SPI_CS(spi->chip_select)); + val |= ORION_SPI_CS(spi->chip_select); /* * Chip select logic is inverted from spi_set_cs(). For lines using a @@ -350,9 +356,13 @@ static void orion_spi_set_cs(struct spi_device *spi, bool enable) * doesn't matter. */ if (!enable) - orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); - else - orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); + val |= 0x1; + + /* + * To avoid toggling unwanted chip selects update the register + * with a single write. + */ + writel(val, ctrl_reg); } static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi) -- cgit v1.2.3 From d68f4c73d729245a47e70eb216fa24bc174ed2e2 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 18 Aug 2021 22:55:56 +0200 Subject: spi: coldfire-qspi: Use clk_disable_unprepare in the remove function 'clk_prepare_enable()' is used in the probe, so 'clk_disable_unprepare()' should be used in the remove function to be consistent. Fixes: 499de01c5c0b ("spi: coldfire-qspi: Use clk_prepare_enable and clk_disable_unprepare") Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/ee91792ddba61342b0d3284cd4558a2b0016c4e7.1629319838.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown --- drivers/spi/spi-coldfire-qspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 8996115ce736..263ce9047327 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -444,7 +444,7 @@ static int mcfqspi_remove(struct platform_device *pdev) mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); mcfqspi_cs_teardown(mcfqspi); - clk_disable(mcfqspi->clk); + clk_disable_unprepare(mcfqspi->clk); return 0; } -- cgit v1.2.3 From ea4ab99cb58cc9f8d64c0961ff9a059825f304cf Mon Sep 17 00:00:00 2001 From: Matija Glavinic Pecotic Date: Tue, 24 Aug 2021 11:25:56 +0200 Subject: spi: davinci: invoke chipselect callback Davinci needs to configure chipselect on transfer. Fixes: 4a07b8bcd503 ("spi: bitbang: Make chipselect callback optional") Signed-off-by: Matija Glavinic Pecotic Reviewed-by: Alexander Sverdlin Link: https://lore.kernel.org/r/735fb7b0-82aa-5b9b-85e4-53f0c348cc0e@nokia.com Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index e114e6fe5ea5..d112c2cac042 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -213,12 +213,6 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) * line for the controller */ if (spi->cs_gpiod) { - /* - * FIXME: is this code ever executed? This host does not - * set SPI_MASTER_GPIO_SS so this chipselect callback should - * not get called from the SPI core when we are using - * GPIOs for chip select. - */ if (value == BITBANG_CS_ACTIVE) gpiod_set_value(spi->cs_gpiod, 1); else @@ -945,7 +939,7 @@ static int davinci_spi_probe(struct platform_device *pdev) master->bus_num = pdev->id; master->num_chipselect = pdata->num_chipselect; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); - master->flags = SPI_MASTER_MUST_RX; + master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_GPIO_SS; master->setup = davinci_spi_setup; master->cleanup = davinci_spi_cleanup; master->can_dma = davinci_spi_can_dma; -- cgit v1.2.3