Commit 97ca0d6c authored by Mark A. Greer's avatar Mark A. Greer Committed by Mark Brown

spi: omap2-mcspi: Configure hardware when slave driver changes mode

Commit id 2bd16e3e
(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: 2bd16e3e (spi: omap2-mcspi: Do not configure the controller on each transfer unless needed)
Signed-off-by: default avatarMark A. Greer <mgreer@animalcreek.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
Cc: stable@vger.kernel.org
parent 7171511e
...@@ -149,6 +149,7 @@ struct omap2_mcspi_cs { ...@@ -149,6 +149,7 @@ struct omap2_mcspi_cs {
void __iomem *base; void __iomem *base;
unsigned long phys; unsigned long phys;
int word_len; int word_len;
u16 mode;
struct list_head node; struct list_head node;
/* Context save and restore shadow register */ /* Context save and restore shadow register */
u32 chconf0, chctrl0; u32 chconf0, chctrl0;
...@@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, ...@@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
mcspi_write_chconf0(spi, l); mcspi_write_chconf0(spi, l);
cs->mode = spi->mode;
dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
speed_hz, speed_hz,
(spi->mode & SPI_CPHA) ? "trailing" : "leading", (spi->mode & SPI_CPHA) ? "trailing" : "leading",
...@@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) ...@@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
return -ENOMEM; return -ENOMEM;
cs->base = mcspi->base + spi->chip_select * 0x14; cs->base = mcspi->base + spi->chip_select * 0x14;
cs->phys = mcspi->phys + spi->chip_select * 0x14; cs->phys = mcspi->phys + spi->chip_select * 0x14;
cs->mode = 0;
cs->chconf0 = 0; cs->chconf0 = 0;
cs->chctrl0 = 0; cs->chctrl0 = 0;
spi->controller_state = cs; spi->controller_state = cs;
...@@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) ...@@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
cs = spi->controller_state; cs = spi->controller_state;
cd = spi->controller_data; 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); omap2_mcspi_set_enable(spi, 0);
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment