From 7f8fe3d4b9962c775116e14fb5968328f487b0de Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Tue, 1 Jul 2014 20:28:32 -0700 Subject: spi: omap2-mcspi: Configure hardware when slave driver changes mode commit 97ca0d6cc118716840ea443e010cb3d5f2d25eaf upstream. Commit id 2bd16e3e23d9df41592c6b257c59b6860a9cc3ea (spi: omap2-mcspi: Do not configure the controller on each transfer unless needed) does its job too well so omap2_mcspi_setup_transfer() isn't called even when an SPI slave driver changes 'spi->mode'. The result is that the mode requested by the SPI slave driver never takes effect. Fix this by adding the 'mode' member to the omap2_mcspi_cs structure which holds the mode value that the hardware is configured for. When the SPI slave driver changes 'spi->mode' it will be different than the value of this new member and the SPI master driver will know that the hardware must be reconfigured (by calling omap2_mcspi_setup_transfer()). Fixes: 2bd16e3e23 (spi: omap2-mcspi: Do not configure the controller on each transfer unless needed) Signed-off-by: Mark A. Greer Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-omap2-mcspi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/spi') diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index a72127f08e39..a64f1557c156 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -147,6 +147,7 @@ struct omap2_mcspi_cs { void __iomem *base; unsigned long phys; int word_len; + u16 mode; struct list_head node; /* Context save and restore shadow register */ u32 chconf0; @@ -899,6 +900,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, mcspi_write_chconf0(spi, l); + cs->mode = spi->mode; + dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", OMAP2_MCSPI_MAX_FREQ >> div, (spi->mode & SPI_CPHA) ? "trailing" : "leading", @@ -971,6 +974,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; cs->phys = mcspi->phys + spi->chip_select * 0x14; + cs->mode = 0; cs->chconf0 = 0; spi->controller_state = cs; /* Link this to context save list */ @@ -1051,6 +1055,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) cs = spi->controller_state; cd = spi->controller_data; + /* + * The slave driver could have changed spi->mode in which case + * it will be different from cs->mode (the current hardware setup). + * If so, set par_override (even though its not a parity issue) so + * omap2_mcspi_setup_transfer will be called to configure the hardware + * with the correct mode on the first iteration of the loop below. + */ + if (spi->mode != cs->mode) + par_override = 1; + omap2_mcspi_set_enable(spi, 0); list_for_each_entry(t, &m->transfers, transfer_list) { if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { -- cgit v1.2.3