Message ID | 20210816050228.3223661-1-nathan@nathanrossi.com (mailing list archive) |
---|---|
State | Accepted |
Commit | ed14666c3f877c4c2a428a92bfeebfba3a4cfe2e |
Headers | show |
Series | spi: orion: Prevent incorrect chip select behaviour | expand |
On Mon, 16 Aug 2021 05:02:28 +0000, Nathan Rossi wrote: > From: Nathan Rossi <nathan.rossi@digi.com> > > 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. > > [...] Applied to https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next Thanks! [1/1] spi: orion: Prevent incorrect chip select behaviour commit: ed14666c3f877c4c2a428a92bfeebfba3a4cfe2e All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 34b31aba39..e8de3cbbfb 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)